libdecaf
Loading...
Searching...
No Matches
ed255.hxx
Go to the documentation of this file.
1
15#ifndef __DECAF_ED255_HXX__
16#define __DECAF_ED255_HXX__ 1
17/*
18 * Example Decaf cyrpto routines, C++ wrapper.
19 * @warning These are merely examples, though they ought to be secure. But real
20 * protocols will decide differently on magic numbers, formats, which items to
21 * hash, etc.
22 * @warning Experimental! The names, parameter orders etc are likely to change.
23 */
24
25#include <decaf/eddsa.hxx>
26#include <decaf/point_255.hxx>
27#include <decaf/ed255.h>
28
29#include <decaf/shake.hxx>
30#include <decaf/sha512.hxx>
31
33#if __cplusplus >= 201103L
34#define DECAF_NOEXCEPT noexcept
35#else
36#define DECAF_NOEXCEPT throw()
37#endif
41namespace decaf {
42
44template <typename Group> struct EdDSA;
45
47template<> struct EdDSA<Ristretto> {
48
50template<class CRTP, Prehashed> class Signing;
51template<class CRTP, Prehashed> class Verification;
52class PublicKeyBase;
53class PrivateKeyBase;
54typedef class PrivateKeyBase PrivateKey, PrivateKeyPure, PrivateKeyPh;
55typedef class PublicKeyBase PublicKey, PublicKeyPure, PublicKeyPh;
66#if DECAF_EDDSA_25519_SUPPORTS_CONTEXTLESS_SIGS
67static inline const Block NO_CONTEXT() { return Block(DECAF_ED25519_NO_CONTEXT,0); }
68#else
69static inline const Block NO_CONTEXT() { return Block(NULL,0); }
70#endif
71
73class Prehash : public SHA512 {
74private:
76 typedef SHA512 Super;
77 SecureBuffer context_;
78 template<class T, Prehashed Ph> friend class Signing;
79 template<class T, Prehashed Ph> friend class Verification;
80
81 void init() /*throw(LengthException)*/ {
82 Super::reset();
83
84 if (context_.size() > 255) {
85 throw LengthException();
86 }
87
89 }
92public:
94 static const size_t OUTPUT_BYTES = Super::DEFAULT_OUTPUT_BYTES;
95
97 Prehash(const Block &context = NO_CONTEXT()) /*throw(LengthException)*/ {
98 context_ = context;
99 init();
100 }
101
103 void reset() DECAF_NOEXCEPT { init(); }
104
106 SecureBuffer final() /*throw(std::bad_alloc)*/ {
107 SecureBuffer ret = Super::final(OUTPUT_BYTES);
108 reset();
109 return ret;
110 }
111
113 void final(Buffer &b) /*throw(LengthException)*/ {
114 if (b.size() != OUTPUT_BYTES) throw LengthException();
115 Super::final(b);
116 reset();
117 }
118};
119
121template<class CRTP, Prehashed ph> class Signing;
122
124template<class CRTP> class Signing<CRTP,PURE> {
125public:
134 const Block &message,
135 const Block &context = NO_CONTEXT()
136 ) const /* throw(LengthException, std::bad_alloc) */ {
137 if (context.size() > 255) {
138 throw LengthException();
139 }
140
141 SecureBuffer out(CRTP::SIG_BYTES);
143 out.data(),
144 ((const CRTP*)this)->keypair_,
145 message.data(),
146 message.size(),
147 0,
148 context.data(),
149 static_cast<uint8_t>(context.size())
150 );
151 return out;
152 }
153};
154
156template<class CRTP> class Signing<CRTP,PREHASHED> {
157public:
159 inline SecureBuffer sign_prehashed ( const Prehash &ph ) const /*throw(std::bad_alloc)*/ {
160 SecureBuffer out(CRTP::SIG_BYTES);
162 out.data(),
163 ((const CRTP*)this)->keypair_,
164 (const decaf_ed25519_prehash_ctx_s*)ph.wrapped,
165 ph.context_.data(),
166 static_cast<uint8_t>(ph.context_.size())
167 );
168 return out;
169 }
170
173 const Block &message,
174 const Block &context = NO_CONTEXT()
175 ) const /*throw(LengthException,CryptoException)*/ {
176 Prehash ph(context);
177 ph += message;
178 return sign_prehashed(ph);
179 }
180};
181
183class PrivateKeyBase
184 : public Serializable<PrivateKeyBase>
185 , public Signing<PrivateKeyBase,PURE>
186 , public Signing<PrivateKeyBase,PREHASHED> {
187public:
189 typedef class PublicKeyBase PublicKey;
190private:
192 friend class PublicKeyBase;
193 friend class Signing<PrivateKey,PURE>;
194 friend class Signing<PrivateKey,PREHASHED>;
198 decaf_eddsa_25519_keypair_t keypair_;
199
200public:
203
205 static const size_t SIG_BYTES = DECAF_EDDSA_25519_SIGNATURE_BYTES;
206
208 static const size_t SER_BYTES = DECAF_EDDSA_25519_PRIVATE_BYTES;
209
210
212 inline explicit PrivateKeyBase(const NOINIT&) DECAF_NOEXCEPT { }
213
215 inline explicit PrivateKeyBase(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT { *this = b; }
216
218 inline PrivateKeyBase(const PrivateKeyBase &k) DECAF_NOEXCEPT { *this = k; }
219
221 inline explicit PrivateKeyBase(Rng &r) DECAF_NOEXCEPT {
223 decaf_ed25519_derive_keypair(keypair_, priv.data());
224 }
225
227 inline PrivateKeyBase &operator=(const PrivateKey &k) DECAF_NOEXCEPT {
228 memcpy(keypair_,k.keypair_,sizeof(keypair_));
229 return *this;
230 }
231
234
236 inline PrivateKeyBase &operator=(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT {
237 decaf_ed25519_derive_keypair(keypair_, b.data());
238 return *this;
239 }
240
242 inline size_t ser_size() const DECAF_NOEXCEPT { return SER_BYTES; }
243
245 inline void serialize_into(unsigned char *x) const DECAF_NOEXCEPT {
247 }
248
250 inline SecureBuffer convert_to_x() const {
253 serialize_into(priv.data());
255 return out;
256 }
257
259 inline PublicKey pub() const DECAF_NOEXCEPT {
260 PublicKey pub(*this);
261 return pub;
262 }
263}; /* class PrivateKey */
264
266template<class CRTP> class Verification<CRTP,PURE> {
267public:
269 inline decaf_error_t DECAF_WARN_UNUSED verify_noexcept (
271 const Block &message,
272 const Block &context = NO_CONTEXT()
273 ) const /*DECAF_NOEXCEPT*/ {
274 if (context.size() > 255) {
275 return DECAF_FAILURE;
276 }
277
278 return decaf_ed25519_verify (
279 sig.data(),
280 ((const CRTP*)this)->pub_.data(),
281 message.data(),
282 message.size(),
283 0,
284 context.data(),
285 static_cast<uint8_t>(context.size())
286 );
287 }
288
296 inline void verify (
298 const Block &message,
299 const Block &context = NO_CONTEXT()
300 ) const /*throw(LengthException,CryptoException)*/ {
301 if (context.size() > 255) {
302 throw LengthException();
303 }
304
305 if (DECAF_SUCCESS != verify_noexcept( sig, message, context )) {
306 throw CryptoException();
307 }
308 }
309};
310
312template<class CRTP> class Verification<CRTP,PREHASHED> {
313public:
315 inline decaf_error_t DECAF_WARN_UNUSED verify_prehashed_noexcept (
317 const Prehash &ph
318 ) const /*DECAF_NOEXCEPT*/ {
320 sig.data(),
321 ((const CRTP*)this)->pub_.data(),
322 (const decaf_ed25519_prehash_ctx_s*)ph.wrapped,
323 ph.context_.data(),
324 ph.context_.size()
325 );
326 }
327
329 inline void verify_prehashed (
331 const Prehash &ph
332 ) const /*throw(CryptoException)*/ {
334 sig.data(),
335 ((const CRTP*)this)->pub_.data(),
336 (const decaf_ed25519_prehash_ctx_s*)ph.wrapped,
337 ph.context_.data(),
338 static_cast<uint8_t>(ph.context_.size())
339 )) {
340 throw CryptoException();
341 }
342 }
343
347 const Block &message,
348 const Block &context = NO_CONTEXT()
349 ) const /*throw(LengthException,CryptoException)*/ {
350 Prehash ph(context);
351 ph += message;
352 verify_prehashed(sig,ph);
353 }
354};
355
357class PublicKeyBase
358 : public Serializable<PublicKeyBase>
359 , public Verification<PublicKeyBase,PURE>
360 , public Verification<PublicKeyBase,PREHASHED> {
361public:
363 typedef class PrivateKeyBase PrivateKey;
364
365private:
367 friend class PrivateKeyBase;
368 friend class Verification<PublicKey,PURE>;
369 friend class Verification<PublicKey,PREHASHED>;
370
371private:
376public:
377 /* PERF FUTURE: Pre-cached decoding? Precomputed table?? */
378
381
383 static const size_t SIG_BYTES = DECAF_EDDSA_25519_SIGNATURE_BYTES;
384
386 static const size_t SER_BYTES = DECAF_EDDSA_25519_PRIVATE_BYTES;
387
389 inline explicit PublicKeyBase(const NOINIT&) DECAF_NOEXCEPT : pub_((NOINIT())) { }
390
392 inline explicit PublicKeyBase(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT { *this = b; }
393
395 inline PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT { *this = k; }
396
398 inline explicit PublicKeyBase(const PrivateKey &k) DECAF_NOEXCEPT { *this = k; }
399
401 inline PublicKey &operator=(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT {
402 memcpy(pub_.data(),b.data(),b.size());
403 return *this;
404 }
405
407 inline PublicKey &operator=(const PublicKey &p) DECAF_NOEXCEPT {
408 return *this = p.pub_;
409 }
410
412 inline PublicKey &operator=(const PrivateKey &p) DECAF_NOEXCEPT {
414 return *this;
415 }
416
418 inline size_t ser_size() const DECAF_NOEXCEPT { return SER_BYTES; }
419
421 inline void serialize_into(unsigned char *x) const DECAF_NOEXCEPT {
422 memcpy(x,pub_.data(), pub_.size());
423 }
424
426 inline SecureBuffer convert_to_x() const {
429 return out;
430 }
431}; /* class PublicKey */
432
433}; /* template<> struct EdDSA<Ristretto> */
434
435#undef DECAF_NOEXCEPT
436} /* namespace decaf */
437
438#endif /* __DECAF_ED255_HXX__ */
A reference to a block of data, which (when accessed through this base class) is const.
Definition secure_buffer.hxx:159
const unsigned char * data() const DECAF_NOEXCEPT
Get const data.
Definition secure_buffer.hxx:199
size_t size() const DECAF_NOEXCEPT
Get the size.
Definition secure_buffer.hxx:208
A reference to a writable block of data.
Definition secure_buffer.hxx:270
const unsigned char * data() const DECAF_NOEXCEPT
Get const data.
Definition secure_buffer.hxx:282
An exception for when crypto (ie point decode) has failed.
Definition secure_buffer.hxx:119
void reset() DECAF_NOEXCEPT
Reset this hash.
Definition ed255.hxx:103
Prehash(const Block &context=NO_CONTEXT())
Create the prehash.
Definition ed255.hxx:97
Ristretto Group
Underlying group.
Definition ed255.hxx:202
PrivateKeyBase(const NOINIT &) DECAF_NOEXCEPT
Create but don't initialize.
Definition ed255.hxx:212
PrivateKeyBase(const PrivateKeyBase &k) DECAF_NOEXCEPT
Copy constructor.
Definition ed255.hxx:218
void serialize_into(unsigned char *x) const DECAF_NOEXCEPT
Serialize into a buffer.
Definition ed255.hxx:245
PrivateKeyBase(Rng &r) DECAF_NOEXCEPT
Create at random.
Definition ed255.hxx:221
PrivateKeyBase & operator=(const PrivateKey &k) DECAF_NOEXCEPT
Copy assignment.
Definition ed255.hxx:227
SecureBuffer convert_to_x() const
Convert to X format (to be used for key exchange)
Definition ed255.hxx:250
class PublicKeyBase PublicKey
Type of public key corresponding to this private key.
Definition ed255.hxx:189
PublicKey pub() const DECAF_NOEXCEPT
Return the corresponding public key.
Definition ed255.hxx:259
size_t ser_size() const DECAF_NOEXCEPT
Serialization size.
Definition ed255.hxx:242
PrivateKeyBase & operator=(const FixedBlock< SER_BYTES > &b) DECAF_NOEXCEPT
Assignment from string.
Definition ed255.hxx:236
PrivateKeyBase(const FixedBlock< SER_BYTES > &b) DECAF_NOEXCEPT
Read a private key from a string.
Definition ed255.hxx:215
~PrivateKeyBase()
Create at random.
Definition ed255.hxx:233
void serialize_into(unsigned char *x) const DECAF_NOEXCEPT
Serialize into a buffer.
Definition ed255.hxx:421
PublicKeyBase(const NOINIT &) DECAF_NOEXCEPT
Create but don't initialize.
Definition ed255.hxx:389
PublicKeyBase(const PrivateKey &k) DECAF_NOEXCEPT
Copy constructor.
Definition ed255.hxx:398
class PrivateKeyBase PrivateKey
Private key corresponding to this type of public key.
Definition ed255.hxx:363
PublicKey & operator=(const FixedBlock< SER_BYTES > &b) DECAF_NOEXCEPT
Assignment from string.
Definition ed255.hxx:401
PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT
Copy constructor.
Definition ed255.hxx:395
Ristretto Group
Underlying group.
Definition ed255.hxx:380
PublicKeyBase(const FixedBlock< SER_BYTES > &b) DECAF_NOEXCEPT
Read a private key from a string.
Definition ed255.hxx:392
PublicKey & operator=(const PrivateKey &p) DECAF_NOEXCEPT
Assignment from private key.
Definition ed255.hxx:412
size_t ser_size() const DECAF_NOEXCEPT
Serialization size.
Definition ed255.hxx:418
PublicKey & operator=(const PublicKey &p) DECAF_NOEXCEPT
Assignment from public key.
Definition ed255.hxx:407
SecureBuffer convert_to_x() const
Convert to X format (to be used for key exchange)
Definition ed255.hxx:426
SecureBuffer sign_with_prehash(const Block &message, const Block &context=NO_CONTEXT()) const
Sign a message using the prehasher.
Definition ed255.hxx:172
SecureBuffer sign_prehashed(const Prehash &ph) const
Sign a prehash context, and reset the context.
Definition ed255.hxx:159
SecureBuffer sign(const Block &message, const Block &context=NO_CONTEXT()) const
Sign a message.
Definition ed255.hxx:133
decaf_error_t DECAF_WARN_UNUSED verify_prehashed_noexcept(const FixedBlock< DECAF_EDDSA_25519_SIGNATURE_BYTES > &sig, const Prehash &ph) const
Verify that a signature is valid for a given prehashed message, given the context.
Definition ed255.hxx:315
void verify_with_prehash(const FixedBlock< DECAF_EDDSA_25519_SIGNATURE_BYTES > &sig, const Block &message, const Block &context=NO_CONTEXT()) const
Hash and verify a message, using the prehashed verification mode.
Definition ed255.hxx:345
void verify_prehashed(const FixedBlock< DECAF_EDDSA_25519_SIGNATURE_BYTES > &sig, const Prehash &ph) const
Verify that a signature is valid for a given prehashed message, given the context.
Definition ed255.hxx:329
decaf_error_t DECAF_WARN_UNUSED verify_noexcept(const FixedBlock< DECAF_EDDSA_25519_SIGNATURE_BYTES > &sig, const Block &message, const Block &context=NO_CONTEXT()) const
Verify a signature, returning DECAF_FAILURE if verification fails.
Definition ed255.hxx:269
void verify(const FixedBlock< DECAF_EDDSA_25519_SIGNATURE_BYTES > &sig, const Block &message, const Block &context=NO_CONTEXT()) const
Verify a signature, throwing an exception if verification fails.
Definition ed255.hxx:296
A fixed-size stack-allocated buffer (for DECAF_NOEXCEPT semantics)
Definition secure_buffer.hxx:337
A fixed-size block.
Definition secure_buffer.hxx:253
An exception for when crypto (ie point decode) has failed.
Definition secure_buffer.hxx:126
Prototype of a random number generator.
Definition secure_buffer.hxx:138
SHA512 wrapper function.
Definition sha512.hxx:29
Base class of objects which support serialization.
Definition secure_buffer.hxx:89
decaf_error_t
Another boolean type used to indicate success or failure.
Definition common.h:120
@ DECAF_FAILURE
The operation failed.
Definition common.h:122
@ DECAF_SUCCESS
The operation succeeded.
Definition common.h:121
void decaf_ed25519_convert_public_key_to_x25519(uint8_t x[DECAF_X25519_PUBLIC_BYTES], const uint8_t ed[DECAF_EDDSA_25519_PUBLIC_BYTES])
EdDSA to ECDH public key conversion Deserialize the point to get y on Edwards curve,...
Definition decaf.c:1335
A group of prime order p, based on Curve25519.
void DECAF_API_VIS decaf_ed25519_prehash_init(decaf_ed25519_prehash_ctx_t hash) DECAF_NOINLINE
Prehash initialization, with contexts if supported.
#define decaf_ed25519_prehash_ctx_s
Prehash context (raw), because each EdDSA instance has a different prehash.
Definition ed255.h:47
void DECAF_API_VIS decaf_ed25519_keypair_sign_prehash(uint8_t signature[DECAF_EDDSA_25519_SIGNATURE_BYTES], const decaf_eddsa_25519_keypair_t keypair, const decaf_ed25519_prehash_ctx_t hash, const uint8_t *context, uint8_t context_len) DECAF_NOINLINE
EdDSA signing with prehash.
void DECAF_API_VIS decaf_ed25519_convert_private_key_to_x25519(uint8_t x[DECAF_X25519_PRIVATE_BYTES], const uint8_t ed[DECAF_EDDSA_25519_PRIVATE_BYTES]) DECAF_NONNULL DECAF_NOINLINE
EdDSA to ECDH private key conversion Using the appropriate hash function, hash the EdDSA private key ...
decaf_error_t DECAF_API_VIS decaf_ed25519_verify_prehash(const uint8_t signature[DECAF_EDDSA_25519_SIGNATURE_BYTES], const uint8_t pubkey[DECAF_EDDSA_25519_PUBLIC_BYTES], const decaf_ed25519_prehash_ctx_t hash, const uint8_t *context, uint8_t context_len) DECAF_NOINLINE
EdDSA signature verification.
#define DECAF_EDDSA_25519_PRIVATE_BYTES
Number of bytes in an EdDSA private key.
Definition ed255.h:30
void DECAF_API_VIS decaf_ed25519_keypair_destroy(decaf_eddsa_25519_keypair_t keypair) DECAF_NONNULL DECAF_NOINLINE
EdDSA keypair destructor.
void DECAF_API_VIS decaf_ed25519_derive_keypair(decaf_eddsa_25519_keypair_t keypair, const uint8_t privkey[DECAF_EDDSA_25519_PRIVATE_BYTES]) DECAF_NONNULL DECAF_NOINLINE
EdDSA keypair scheduling.
void DECAF_API_VIS decaf_ed25519_keypair_sign(uint8_t signature[DECAF_EDDSA_25519_SIGNATURE_BYTES], const decaf_eddsa_25519_keypair_t keypair, const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, uint8_t context_len) DECAF_NOINLINE
EdDSA signing.
void DECAF_API_VIS decaf_ed25519_keypair_extract_private_key(uint8_t privkey[DECAF_EDDSA_25519_PRIVATE_BYTES], const decaf_eddsa_25519_keypair_t keypair) DECAF_NONNULL DECAF_NOINLINE
Extract the private key from an EdDSA keypair.
decaf_error_t DECAF_API_VIS decaf_ed25519_verify(const uint8_t signature[DECAF_EDDSA_25519_SIGNATURE_BYTES], const uint8_t pubkey[DECAF_EDDSA_25519_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, uint8_t context_len) DECAF_NOINLINE
EdDSA signature verification.
void DECAF_API_VIS decaf_ed25519_keypair_extract_public_key(uint8_t pubkey[DECAF_EDDSA_25519_PUBLIC_BYTES], const decaf_eddsa_25519_keypair_t keypair) DECAF_NONNULL DECAF_NOINLINE
Extract the public key from an EdDSA keypair.
#define DECAF_EDDSA_25519_SIGNATURE_BYTES
Number of bytes in an EdDSA private key.
Definition ed255.h:33
Namespace for all C++ decaf objects.
Definition decaf.hxx:22
std::vector< unsigned char, SanitizingAllocator< unsigned char, 0 > > SecureBuffer
A variant of std::vector which securely zerozes its state when destructed.
Definition secure_buffer.hxx:79
@ PURE
Sign the message itself.
Definition eddsa.hxx:22
@ PREHASHED
Sign the hash of the message.
Definition eddsa.hxx:23
#define DECAF_X25519_PRIVATE_BYTES
Number of bytes in an x25519 private key.
Definition point_255.h:65
SHA512 instance, C++ wrapper.
SHA-3-n and SHAKE-n instances, C++ wrapper.
static const Block NO_CONTEXT()
Signatures support a "context" block, which allows you to domain separate them if (for some reason) i...
Definition ed255.hxx:69
A public key for crypto over some Group.
Definition ed255.hxx:44
Passed to constructors to avoid (conservative) initialization.
Definition secure_buffer.hxx:133
Curve25519/Decaf instantiation of group.
Definition point_255.hxx:55
Hash context for SHA-512.
Definition sha512.h:22