libdecaf
ed448.hxx
Go to the documentation of this file.
1 
15 #ifndef __DECAF_ED448_HXX__
16 #define __DECAF_ED448_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_448.hxx>
27 #include <decaf/ed448.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
41 namespace decaf {
42 
44 template <typename Group> struct EdDSA;
45 
47 template<> struct EdDSA<Ed448Goldilocks> {
48 
50 template<class CRTP, Prehashed> class Signing;
51 template<class CRTP, Prehashed> class Verification;
52 class PublicKeyBase;
53 class PrivateKeyBase;
54 typedef class PrivateKeyBase PrivateKey, PrivateKeyPure, PrivateKeyPh;
55 typedef class PublicKeyBase PublicKey, PublicKeyPure, PublicKeyPh;
66 #if DECAF_EDDSA_448_SUPPORTS_CONTEXTLESS_SIGS
67 static inline const Block NO_CONTEXT() { return Block(DECAF_ED448_NO_CONTEXT,0); }
68 #else
69 static inline const Block NO_CONTEXT() { return Block(NULL,0); }
70 #endif
71 
73 class Prehash : public SHAKE<256> {
74 private:
76  typedef SHAKE<256> 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 
88  decaf_ed448_prehash_init((decaf_shake256_ctx_s *)wrapped);
89  }
92 public:
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 
121 template<class CRTP, Prehashed ph> class Signing;
122 
124 template<class CRTP> class Signing<CRTP,PURE> {
125 public:
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 
156 template<class CRTP> class Signing<CRTP,PREHASHED> {
157 public:
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_ed448_prehash_ctx_s*)ph.wrapped,
165  ph.context_.data(),
166  static_cast<uint8_t>(ph.context_.size())
167  );
168  return out;
169  }
170 
172  inline SecureBuffer sign_with_prehash (
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 
183 class PrivateKeyBase
184  : public Serializable<PrivateKeyBase>
185  , public Signing<PrivateKeyBase,PURE>
186  , public Signing<PrivateKeyBase,PREHASHED> {
187 public:
189  typedef class PublicKeyBase PublicKey;
190 private:
192  friend class PublicKeyBase;
193  friend class Signing<PrivateKey,PURE>;
194  friend class Signing<PrivateKey,PREHASHED>;
198  decaf_eddsa_448_keypair_t keypair_;
199 
200 public:
203 
205  static const size_t SIG_BYTES = DECAF_EDDSA_448_SIGNATURE_BYTES;
206 
208  static const size_t SER_BYTES = DECAF_EDDSA_448_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_ed448_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_ed448_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());
254  decaf_ed448_convert_private_key_to_x448(out.data(), 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 
266 template<class CRTP> class Verification<CRTP,PURE> {
267 public:
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_ed448_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 
312 template<class CRTP> class Verification<CRTP,PREHASHED> {
313 public:
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_ed448_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_ed448_prehash_ctx_s*)ph.wrapped,
337  ph.context_.data(),
338  static_cast<uint8_t>(ph.context_.size())
339  )) {
340  throw CryptoException();
341  }
342  }
343 
345  inline void verify_with_prehash (
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 
357 class PublicKeyBase
358  : public Serializable<PublicKeyBase>
359  , public Verification<PublicKeyBase,PURE>
360  , public Verification<PublicKeyBase,PREHASHED> {
361 public:
363  typedef class PrivateKeyBase PrivateKey;
364 
365 private:
367  friend class PrivateKeyBase;
368  friend class Verification<PublicKey,PURE>;
369  friend class Verification<PublicKey,PREHASHED>;
370 
371 private:
376 public:
377  /* PERF FUTURE: Pre-cached decoding? Precomputed table?? */
378 
381 
383  static const size_t SIG_BYTES = DECAF_EDDSA_448_SIGNATURE_BYTES;
384 
386  static const size_t SER_BYTES = DECAF_EDDSA_448_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 {
413  decaf_ed448_keypair_extract_public_key(pub_.data(), p.keypair_);
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 {
428  decaf_ed448_convert_public_key_to_x448(out.data(), pub_.data());
429  return out;
430  }
431 }; /* class PublicKey */
432 
433 }; /* template<> struct EdDSA<Ed448Goldilocks> */
434 
435 #undef DECAF_NOEXCEPT
436 } /* namespace decaf */
437 
438 #endif /* __DECAF_ED448_HXX__ */
A reference to a block of data, which (when accessed through this base class) is const.
Definition: secure_buffer.hxx:159
size_t size() const DECAF_NOEXCEPT
Get the size.
Definition: secure_buffer.hxx:208
const unsigned char * data() const DECAF_NOEXCEPT
Get const data.
Definition: secure_buffer.hxx:199
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: ed448.hxx:103
Prehash(const Block &context=NO_CONTEXT())
Create the prehash.
Definition: ed448.hxx:97
void serialize_into(unsigned char *x) const DECAF_NOEXCEPT
Serialize into a buffer.
Definition: ed448.hxx:245
PrivateKeyBase & operator=(const PrivateKey &k) DECAF_NOEXCEPT
Copy assignment.
Definition: ed448.hxx:227
~PrivateKeyBase()
Create at random.
Definition: ed448.hxx:233
PrivateKeyBase & operator=(const FixedBlock< SER_BYTES > &b) DECAF_NOEXCEPT
Assignment from string.
Definition: ed448.hxx:236
PrivateKeyBase(const FixedBlock< SER_BYTES > &b) DECAF_NOEXCEPT
Read a private key from a string.
Definition: ed448.hxx:215
PrivateKeyBase(const PrivateKeyBase &k) DECAF_NOEXCEPT
Copy constructor.
Definition: ed448.hxx:218
size_t ser_size() const DECAF_NOEXCEPT
Serialization size.
Definition: ed448.hxx:242
class PublicKeyBase PublicKey
Type of public key corresponding to this private key.
Definition: ed448.hxx:189
PrivateKeyBase(Rng &r) DECAF_NOEXCEPT
Create at random.
Definition: ed448.hxx:221
PublicKey pub() const DECAF_NOEXCEPT
Return the corresponding public key.
Definition: ed448.hxx:259
PrivateKeyBase(const NOINIT &) DECAF_NOEXCEPT
Create but don't initialize.
Definition: ed448.hxx:212
Ed448Goldilocks Group
Underlying group.
Definition: ed448.hxx:202
SecureBuffer convert_to_x() const
Convert to X format (to be used for key exchange)
Definition: ed448.hxx:250
PublicKey & operator=(const PrivateKey &p) DECAF_NOEXCEPT
Assignment from private key.
Definition: ed448.hxx:412
PublicKeyBase(const NOINIT &) DECAF_NOEXCEPT
Create but don't initialize.
Definition: ed448.hxx:389
SecureBuffer convert_to_x() const
Convert to X format (to be used for key exchange)
Definition: ed448.hxx:426
PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT
Copy constructor.
Definition: ed448.hxx:395
class PrivateKeyBase PrivateKey
Private key corresponding to this type of public key.
Definition: ed448.hxx:363
PublicKeyBase(const FixedBlock< SER_BYTES > &b) DECAF_NOEXCEPT
Read a private key from a string.
Definition: ed448.hxx:392
PublicKey & operator=(const PublicKey &p) DECAF_NOEXCEPT
Assignment from public key.
Definition: ed448.hxx:407
PublicKeyBase(const PrivateKey &k) DECAF_NOEXCEPT
Copy constructor.
Definition: ed448.hxx:398
Ed448Goldilocks Group
Underlying group.
Definition: ed448.hxx:380
void serialize_into(unsigned char *x) const DECAF_NOEXCEPT
Serialize into a buffer.
Definition: ed448.hxx:421
PublicKey & operator=(const FixedBlock< SER_BYTES > &b) DECAF_NOEXCEPT
Assignment from string.
Definition: ed448.hxx:401
size_t ser_size() const DECAF_NOEXCEPT
Serialization size.
Definition: ed448.hxx:418
SecureBuffer sign_prehashed(const Prehash &ph) const
Sign a prehash context, and reset the context.
Definition: ed448.hxx:159
SecureBuffer sign(const Block &message, const Block &context=NO_CONTEXT()) const
Sign a message.
Definition: ed448.hxx:133
decaf_error_t DECAF_WARN_UNUSED verify_prehashed_noexcept(const FixedBlock< DECAF_EDDSA_448_SIGNATURE_BYTES > &sig, const Prehash &ph) const
Verify that a signature is valid for a given prehashed message, given the context.
Definition: ed448.hxx:315
void verify_prehashed(const FixedBlock< DECAF_EDDSA_448_SIGNATURE_BYTES > &sig, const Prehash &ph) const
Verify that a signature is valid for a given prehashed message, given the context.
Definition: ed448.hxx:329
decaf_error_t DECAF_WARN_UNUSED verify_noexcept(const FixedBlock< DECAF_EDDSA_448_SIGNATURE_BYTES > &sig, const Block &message, const Block &context=NO_CONTEXT()) const
Verify a signature, returning DECAF_FAILURE if verification fails.
Definition: ed448.hxx:269
void verify(const FixedBlock< DECAF_EDDSA_448_SIGNATURE_BYTES > &sig, const Block &message, const Block &context=NO_CONTEXT()) const
Verify a signature, throwing an exception if verification fails.
Definition: ed448.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
Variable-output-length SHAKE.
Definition: shake.hxx:151
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
A group of prime order p, based on Ed448-Goldilocks.
void DECAF_API_VIS decaf_ed448_keypair_extract_public_key(uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES], const decaf_eddsa_448_keypair_t keypair) DECAF_NONNULL DECAF_NOINLINE
Extract the public key from an EdDSA keypair.
decaf_error_t DECAF_API_VIS decaf_ed448_verify_prehash(const uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES], const decaf_ed448_prehash_ctx_t hash, const uint8_t *context, uint8_t context_len) DECAF_NOINLINE
EdDSA signature verification.
void DECAF_API_VIS decaf_ed448_keypair_sign(uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES], const decaf_eddsa_448_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.
#define decaf_ed448_prehash_ctx_s
Prehash context (raw), because each EdDSA instance has a different prehash.
Definition: ed448.h:45
#define DECAF_EDDSA_448_SIGNATURE_BYTES
Number of bytes in an EdDSA private key.
Definition: ed448.h:33
#define DECAF_EDDSA_448_PRIVATE_BYTES
Number of bytes in an EdDSA private key.
Definition: ed448.h:30
void DECAF_API_VIS decaf_ed448_keypair_extract_private_key(uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES], const decaf_eddsa_448_keypair_t keypair) DECAF_NONNULL DECAF_NOINLINE
Extract the private key from an EdDSA keypair.
void DECAF_API_VIS decaf_ed448_keypair_destroy(decaf_eddsa_448_keypair_t keypair) DECAF_NONNULL DECAF_NOINLINE
EdDSA keypair destructor.
decaf_error_t DECAF_API_VIS decaf_ed448_verify(const uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[DECAF_EDDSA_448_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_ed448_derive_keypair(decaf_eddsa_448_keypair_t keypair, const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES]) DECAF_NONNULL DECAF_NOINLINE
EdDSA keypair scheduling.
void DECAF_API_VIS decaf_ed448_convert_private_key_to_x448(uint8_t x[DECAF_X448_PRIVATE_BYTES], const uint8_t ed[DECAF_EDDSA_448_PRIVATE_BYTES]) DECAF_NONNULL DECAF_NOINLINE
EdDSA to ECDH private key conversion Using the appropriate hash function, hash the EdDSA private key ...
void DECAF_API_VIS decaf_ed448_prehash_init(decaf_ed448_prehash_ctx_t hash) DECAF_NOINLINE
Prehash initialization, with contexts if supported.
void DECAF_API_VIS decaf_ed448_keypair_sign_prehash(uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES], const decaf_eddsa_448_keypair_t keypair, const decaf_ed448_prehash_ctx_t hash, const uint8_t *context, uint8_t context_len) DECAF_NOINLINE
EdDSA signing with prehash.
void decaf_ed448_convert_public_key_to_x448(uint8_t x[DECAF_X448_PUBLIC_BYTES], const uint8_t ed[DECAF_EDDSA_448_PUBLIC_BYTES])
EdDSA to ECDH public key conversion Deserialize the point to get y on Edwards curve,...
Definition: decaf.c:1335
Namespace for all libdecaf C++ objects.
Definition: ed255.hxx:41
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_X448_PRIVATE_BYTES
Number of bytes in an x448 private key.
Definition: point_448.h:65
SHA512 instance, C++ wrapper.
SHA-3-n and SHAKE-n instances, C++ wrapper.
Ed448-Goldilocks/Decaf instantiation of group.
Definition: point_448.hxx:55
static const Block NO_CONTEXT()
Signatures support a "context" block, which allows you to domain separate them if (for some reason) i...
Definition: ed448.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