Crypto++  7.0
Free C++ class library of cryptographic schemes
xed25519.h
Go to the documentation of this file.
1 // xed25519.h - written and placed in public domain by Jeffrey Walton
2 // Crypto++ specific implementation wrapped around Andrew
3 // Moon's public domain curve25519-donna and ed25519-donna,
4 // https://github.com/floodyberry/curve25519-donna and
5 // https://github.com/floodyberry/ed25519-donna.
6 
7 // Typically the key agreement classes encapsulate their data more
8 // than x25519 does below. They are a little more accessible
9 // due to crypto_box operations.
10 
11 /// \file xed25519.h
12 /// \brief Classes for x25519 and ed25519 operations
13 /// \details This implementation integrates Andrew Moon's public domain code
14 /// for curve25519-donna and ed25519-donna.
15 /// \details Moving keys into and out of the library proceeds as follows.
16 /// If an Integer class is accepted or returned, then the data is in big
17 /// endian format. That is, the MSB is at byte position 0, and the LSB
18 /// is at byte position 31. The Integer will work as expected, just like
19 /// an int or a long.
20 /// \details If a byte array is accepted, then the byte array is in little
21 /// endian format. That is, the LSB is at byte position 0, and the MSB is
22 /// at byte position 31. This follows the implementation where byte 0 is
23 /// clamed with 248. That is my_arr[0] &= 248 to mask the lower 3 bits.
24 /// \details PKCS8 and X509 keys encoded using ASN.1 follow little endian
25 /// arrays. The format is specified in <A HREF=
26 /// "https:///tools.ietf.org/html/draft-ietf-curdle-pkix">draft-ietf-curdle-pkix</A>.
27 /// \details If you have a little endian array and you want to wrap it in
28 /// an Integer using big endian then you can perform the following:
29 /// <pre>Integer x(my_arr, SECRET_KEYLENGTH, UNSIGNED, LITTLE_ENDIAN_ORDER);</pre>
30 /// \sa Andrew Moon's x22519 GitHub <A
31 /// HREF="https://github.com/floodyberry/curve25519-donna">curve25519-donna</A>,
32 /// ed22519 GitHub <A
33 /// HREF="https://github.com/floodyberry/ed25519-donna">ed25519-donna</A>, and
34 /// <A HREF="https:///tools.ietf.org/html/draft-ietf-curdle-pkix">draft-ietf-curdle-pkix</A>
35 /// \since Crypto++ 8.0
36 
37 #ifndef CRYPTOPP_XED25519_H
38 #define CRYPTOPP_XED25519_H
39 
40 #include "cryptlib.h"
41 #include "pubkey.h"
42 #include "oids.h"
43 
44 NAMESPACE_BEGIN(CryptoPP)
45 
46 class Integer;
47 struct ed25519Signer;
48 struct ed25519Verifier;
49 
50 // ******************** x25519 Agreement ************************* //
51 
52 /// \brief x25519 with key validation
53 /// \since Crypto++ 8.0
55 {
56 public:
57  /// \brief Size of the private key
58  /// \details SECRET_KEYLENGTH is the size of the private key, in bytes.
59  CRYPTOPP_CONSTANT(SECRET_KEYLENGTH = 32)
60  /// \brief Size of the public key
61  /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.
62  CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32)
63  /// \brief Size of the shared key
64  /// \details SHARED_KEYLENGTH is the size of the shared key, in bytes.
65  CRYPTOPP_CONSTANT(SHARED_KEYLENGTH = 32)
66 
67  virtual ~x25519() {}
68 
69  /// \brief Create a x25519 object
70  /// \param y public key
71  /// \param x private key
72  /// \details This constructor creates a x25519 object using existing parameters.
73  /// \note The public key is not validated.
74  x25519(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]);
75 
76  /// \brief Create a x25519 object
77  /// \param x private key
78  /// \details This constructor creates a x25519 object using existing parameters.
79  /// The public key is calculated from the private key.
80  x25519(const byte x[SECRET_KEYLENGTH]);
81 
82  /// \brief Create a x25519 object
83  /// \param y public key
84  /// \param x private key
85  /// \details This constructor creates a x25519 object using existing parameters.
86  /// \note The public key is not validated.
87  x25519(const Integer &y, const Integer &x);
88 
89  /// \brief Create a x25519 object
90  /// \param x private key
91  /// \details This constructor creates a x25519 object using existing parameters.
92  /// The public key is calculated from the private key.
93  x25519(const Integer &x);
94 
95  /// \brief Create a x25519 object
96  /// \param rng RandomNumberGenerator derived class
97  /// \details This constructor creates a new x25519 using the random number generator.
99 
100  /// \brief Create a x25519 object
101  /// \param params public and private key
102  /// \details This constructor creates a x25519 object using existing parameters.
103  /// The <tt>params</tt> can be created with <tt>Save</tt>.
104  /// \note The public key is not validated.
106 
107  /// \brief Create a x25519 object
108  /// \param oid an object identifier
109  /// \details This constructor creates a new x25519 using the specified OID. The public
110  /// and private points are uninitialized.
111  x25519(const OID &oid);
112 
113  /// \brief Clamp a private key
114  /// \param y public key
115  /// \param x private key
116  /// \details ClampKeys() clamps a private key and then regenerates the
117  /// public key from the private key.
118  void ClampKeys(byte y[PUBLIC_KEYLENGTH], byte x[SECRET_KEYLENGTH]) const;
119 
120  /// \brief Determine if private key is clamped
121  /// \param x private key
122  bool IsClamped(const byte x[SECRET_KEYLENGTH]) const;
123 
124  /// \brief Test if a key has small order
125  /// \param y public key
126  bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const;
127 
128  /// \Brief Get the Object Identifier
129  /// \returns the Object Identifier
130  /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
131  /// The default private key format is RFC 5208.
132  OID GetAlgorithmID() const {
133  return m_oid.Empty() ? ASN1::X25519() : m_oid;
134  }
135 
136  /// \Brief Set the Object Identifier
137  /// \param oid the new Object Identifier
138  void SetAlgorithmID(const OID& oid) {
139  m_oid = oid;
140  }
141 
142  // CryptoParameters
143  bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
144  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
145  void AssignFrom(const NameValuePairs &source);
146 
147  // CryptoParameters
149 
150  /// \brief DER encode ASN.1 object
151  /// \param bt BufferedTransformation object
152  /// \details Save() will write the OID associated with algorithm or scheme.
153  /// In the case of public and private keys, this function writes the
154  /// subjectPubicKeyInfo parts.
155  /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
156  /// The default private key format is RFC 5208, which is the old format.
157  /// The old format provides the best interop, and keys will work
158  /// with OpenSSL.
159  /// \sa <A HREF="https://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
160  /// Key Packages</A>
161  void Save(BufferedTransformation &bt) const {
162  DEREncode(bt, 0);
163  }
164 
165  /// \brief DER encode ASN.1 object
166  /// \param bt BufferedTransformation object
167  /// \param v1 flag indicating v1
168  /// \details Save() will write the OID associated with algorithm or scheme.
169  /// In the case of public and private keys, this function writes the
170  /// subjectPubicKeyInfo parts.
171  /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
172  /// The default private key format is RFC 5208.
173  /// \details v1 means INTEGER 0 is written. INTEGER 0 means
174  /// RFC 5208 format, which is the old format. The old format provides
175  /// the best interop, and keys will work with OpenSSL. The other
176  /// option uses INTEGER 1. INTEGER 1 means RFC 5958 format,
177  /// which is the new format.
178  /// \sa <A HREF="https://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
179  /// Key Packages</A>
180  void Save(BufferedTransformation &bt, bool v1) const {
181  DEREncode(bt, v1 ? 0 : 1);
182  }
183 
184  /// \brief BER decode ASN.1 object
185  /// \param bt BufferedTransformation object
186  /// \sa <A HREF="https://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
187  /// Key Packages</A>
189  BERDecode(bt);
190  }
191 
192  // PKCS8PrivateKey
194  void DEREncode(BufferedTransformation &bt) const { DEREncode(bt, 0); }
195  void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
197 
198  /// \brief DER encode ASN.1 object
199  /// \param bt BufferedTransformation object
200  /// \param version indicates version
201  /// \details DEREncode() will write the OID associated with algorithm or
202  /// scheme. In the case of public and private keys, this function writes
203  /// the subjectPubicKeyInfo parts.
204  /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
205  /// The default private key format is RFC 5208.
206  /// \details The value of version is written as the INTEGER. INTEGER 0 means
207  /// RFC 5208 format, which is the old format. The old format provides
208  /// the best interop, and keys will work with OpenSSL. The INTEGER 1
209  /// means RFC 5958 format, which is the new format.
210  void DEREncode(BufferedTransformation &bt, int version) const;
211 
212  /// \brief Determine if OID is valid for this object
213  /// \details BERDecodeAndCheckAlgorithmID() parses the OID from
214  /// <tt>bt</tt> and determines if it valid for this object. The
215  /// problem in practice is there are multiple OIDs available to
216  /// denote curve25519 operations. The OIDs include an old GNU
217  /// OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves,
218  /// and OIDs specified in draft-ietf-curdle-pkix.
219  /// \details By default BERDecodeAndCheckAlgorithmID() accepts an
220  /// OID set by the user, <tt>ASN1::curve25519()</tt> and <tt>ASN1::X25519()</tt>.
221  /// <tt>ASN1::curve25519()</tt> is generic and says "this key is valid for
222  /// curve25519 operations". <tt>ASN1::X25519()</tt> is specific and says
223  /// "this key is valid for x25519 key exchange."
225 
226  // DL_PrivateKey
227  void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params);
228 
229  // SimpleKeyAgreementDomain
230  unsigned int AgreedValueLength() const {return SHARED_KEYLENGTH;}
231  unsigned int PrivateKeyLength() const {return SECRET_KEYLENGTH;}
232  unsigned int PublicKeyLength() const {return PUBLIC_KEYLENGTH;}
233 
234  // SimpleKeyAgreementDomain
235  void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const;
236  void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const;
237  bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const;
238 
239 protected:
242  OID m_oid; // preferred OID
243 };
244 
245 // ****************** ed25519 Signer *********************** //
246 
247 /// \brief ed25519 message accumulator
248 /// \details ed25519 buffers the entire message, and does not
249 /// digest the message incrementally. You should be careful with
250 /// large messages like files on-disk. The behavior is by design
251 /// because Bernstein feels small messages should be authenticated;
252 /// and larger messages will be hashed by the application.
254 {
255  CRYPTOPP_CONSTANT(RESERVE_SIZE=2048+64)
256  CRYPTOPP_CONSTANT(SIGNATURE_LENGTH=64)
257 
258  /// \brief Create a message accumulator
260  Restart();
261  }
262 
263  /// \brief Create a message accumulator
264  /// \details ed25519 does not use a RNG. You can safely use
265  /// NullRNG() because IsProbablistic returns false.
267  CRYPTOPP_UNUSED(rng); Restart();
268  }
269 
270  /// \brief Add data to the accumulator
271  /// \param msg pointer to the data to accumulate
272  /// \param len the size of the data, in bytes
273  void Update(const byte* msg, size_t len) {
274  if (msg && len)
275  m_msg.insert(m_msg.end(), msg, msg+len);
276  }
277 
278  /// \brief Reset the accumulator
279  void Restart() {
280  m_msg.reserve(RESERVE_SIZE);
281  m_msg.resize(SIGNATURE_LENGTH);
282  }
283 
284  /// \brief Retrieve pointer to signature buffer
285  /// \returns pointer to signature buffer
286  byte* signature() {
287  return &m_msg[0];
288  }
289 
290  /// \brief Retrieve pointer to signature buffer
291  /// \returns pointer to signature buffer
292  const byte* signature() const {
293  return &m_msg[0];
294  }
295 
296  /// \brief Retrieve pointer to data buffer
297  /// \returns pointer to data buffer
298  const byte* data() const {
299  return &m_msg[0]+SIGNATURE_LENGTH;
300  }
301 
302  /// \brief Retrieve size of data buffer
303  /// \returns size of the data buffer, in bytes
304  size_t size() const {
305  return m_msg.size()-SIGNATURE_LENGTH;
306  }
307 
308 protected:
309  // TODO: Find an equivalent Crypto++ structure.
310  std::vector<byte, AllocatorWithCleanup<byte> > m_msg;
311 };
312 
313 /// \brief Ed25519 private key
314 /// \details ed25519PrivateKey is somewhat of a hack. It needed to
315 /// provide DL_PrivateKey interface to fit into the existing
316 /// framework, but it lacks a lot of the internals of a true
317 /// DL_PrivateKey. The missing pieces include GroupParameters
318 /// and Point, which provide the low level field operations
319 /// found in traditional implementations like NIST curves over
320 /// prime and binary fields.
321 /// \details ed25519PrivateKey is also unusual because the
322 /// class members of interest are byte arrays and not Integers.
323 /// In addition, the byte arrays are little-endian meaning
324 /// LSB is at element 0 and the MSB is at element 31.
325 /// If you call \ref ed25519PrivateKey::GetPrivateExponent()
326 /// "GetPrivateExponent()" then the little-endian byte array is
327 /// converted to a big-endian Integer() so it can be returned
328 /// the way a caller expects. And calling
329 /// \ref ed25519PrivateKey::SetPrivateExponent "SetPrivateExponent()"
330 /// perfoms a similar internal conversion.
331 /// \since Crypto++ 8.0
333 {
334  /// \brief Size of the private key
335  /// \details SECRET_KEYLENGTH is the size of the private key, in bytes.
336  CRYPTOPP_CONSTANT(SECRET_KEYLENGTH = 32)
337  /// \brief Size of the public key
338  /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.
339  CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32)
340  /// \brief Size of the siganture
341  /// \details SIGNATURE_LENGTH is the size of the signature, in bytes.
342  /// ed25519 is a DL-based signature scheme. The signature is the
343  /// concatenation of <tt>r || s</tt>.
344  CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64)
345 
346  // CryptoMaterial
347  bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
348  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
349  void AssignFrom(const NameValuePairs &source);
350 
351  // GroupParameters
352  OID GetAlgorithmID() const {
353  return m_oid.Empty() ? ASN1::Ed25519() : m_oid;
354  }
355 
356  /// \brief DER encode ASN.1 object
357  /// \param bt BufferedTransformation object
358  /// \details Save() will write the OID associated with algorithm or scheme.
359  /// In the case of public and private keys, this function writes the
360  /// subjectPubicKeyInfo parts.
361  /// \details The default OID is from RFC 8410 using <tt>id-Ed25519</tt>.
362  /// The default private key format is RFC 5208, which is the old format.
363  /// The old format provides the best interop, and keys will work
364  /// with OpenSSL.
365  /// \sa <A HREF="https://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
366  /// Key Packages</A>
367  void Save(BufferedTransformation &bt) const {
368  DEREncode(bt, 0);
369  }
370 
371  /// \brief DER encode ASN.1 object
372  /// \param bt BufferedTransformation object
373  /// \param v1 flag indicating v1
374  /// \details Save() will write the OID associated with algorithm or scheme.
375  /// In the case of public and private keys, this function writes the
376  /// subjectPubicKeyInfo parts.
377  /// \details The default OID is from RFC 8410 using <tt>id-Ed25519</tt>.
378  /// The default private key format is RFC 5208.
379  /// \details v1 means INTEGER 0 is written. INTEGER 0 means
380  /// RFC 5208 format, which is the old format. The old format provides
381  /// the best interop, and keys will work with OpenSSL. The other
382  /// option uses INTEGER 1. INTEGER 1 means RFC 5958 format,
383  /// which is the new format.
384  /// \sa <A HREF="https://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
385  /// Key Packages</A>
386  void Save(BufferedTransformation &bt, bool v1) const {
387  DEREncode(bt, v1 ? 0 : 1);
388  }
389 
390  /// \brief BER decode ASN.1 object
391  /// \param bt BufferedTransformation object
392  /// \sa <A HREF="https://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
393  /// Key Packages</A>
395  BERDecode(bt);
396  }
397 
398  /// \brief Initializes a public key from this key
399  /// \param pub reference to a public key
400  void MakePublicKey(PublicKey &pub) const;
401 
402  // PKCS8PrivateKey
404  void DEREncode(BufferedTransformation &bt) const { DEREncode(bt, 0); }
405  void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
407 
408  /// \brief DER encode ASN.1 object
409  /// \param bt BufferedTransformation object
410  /// \param version indicates version
411  /// \details DEREncode() will write the OID associated with algorithm or
412  /// scheme. In the case of public and private keys, this function writes
413  /// the subjectPubicKeyInfo parts.
414  /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
415  /// The default private key format is RFC 5208.
416  /// \details The value of version is written as the INTEGER. INTEGER 0 means
417  /// RFC 5208 format, which is the old format. The old format provides
418  /// the best interop, and keys will work with OpenSSL. The INTEGER 1
419  /// means RFC 5958 format, which is the new format.
420  void DEREncode(BufferedTransformation &bt, int version) const;
421 
422  /// \brief Determine if OID is valid for this object
423  /// \details BERDecodeAndCheckAlgorithmID() parses the OID from
424  /// <tt>bt</tt> and determines if it valid for this object. The
425  /// problem in practice is there are multiple OIDs available to
426  /// denote curve25519 operations. The OIDs include an old GNU
427  /// OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves,
428  /// and OIDs specified in draft-ietf-curdle-pkix.
429  /// \details By default BERDecodeAndCheckAlgorithmID() accepts an
430  /// OID set by the user, <tt>ASN1::curve25519()</tt> and <tt>ASN1::Ed25519()</tt>.
431  /// <tt>ASN1::curve25519()</tt> is generic and says "this key is valid for
432  /// curve25519 operations". <tt>ASN1::Ed25519()</tt> is specific and says
433  /// "this key is valid for ed25519 signing."
435 
436  // PKCS8PrivateKey
437  void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params);
438  void SetPrivateExponent(const byte x[SECRET_KEYLENGTH]);
439  void SetPrivateExponent(const Integer &x);
440  const Integer& GetPrivateExponent() const;
441 
442  /// \brief Clamp a private key
443  /// \param y public key
444  /// \param x private key
445  /// \details ClampKeys() clamps a private key and then regenerates the
446  /// public key from the private key.
447  void ClampKeys(byte y[PUBLIC_KEYLENGTH], byte x[SECRET_KEYLENGTH]) const;
448 
449  /// \brief Determine if private key is clamped
450  /// \param x private key
451  bool IsClamped(const byte x[SECRET_KEYLENGTH]) const;
452 
453  /// \brief Retrieve private key byte array
454  /// \returns the private key byte array
455  /// \details GetPrivateKeyBytePtr() is used by signing code to call ed25519_sign.
456  const byte* GetPrivateKeyBytePtr() const {
457  return m_sk.begin();
458  }
459 
460  /// \brief Retrieve public key byte array
461  /// \returns the public key byte array
462  /// \details GetPublicKeyBytePtr() is used by signing code to call ed25519_sign.
463  const byte* GetPublicKeyBytePtr() const {
464  return m_pk.begin();
465  }
466 
467 protected:
470  OID m_oid; // preferred OID
471  mutable Integer m_x; // for DL_PrivateKey
472 };
473 
474 /// \brief Ed25519 signature algorithm
475 /// \since Crypto++ 8.0
476 struct ed25519Signer : public PK_Signer
477 {
478  /// \brief Size of the private key
479  /// \details SECRET_KEYLENGTH is the size of the private key, in bytes.
480  CRYPTOPP_CONSTANT(SECRET_KEYLENGTH = 32)
481  /// \brief Size of the public key
482  /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.
483  CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32)
484  /// \brief Size of the siganture
485  /// \details SIGNATURE_LENGTH is the size of the signature, in bytes.
486  /// ed25519 is a DL-based signature scheme. The signature is the
487  /// concatenation of <tt>r || s</tt>.
488  CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64)
489  typedef Integer Element;
490 
491  virtual ~ed25519Signer() {}
492 
493  /// \brief Create a ed25519Signer object
495 
496  /// \brief Create a ed25519Signer object
497  /// \param y public key
498  /// \param x private key
499  /// \details This constructor creates a ed25519Signer object using existing parameters.
500  /// \note The public key is not validated.
501  ed25519Signer(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]);
502 
503  /// \brief Create a ed25519Signer object
504  /// \param x private key
505  /// \details This constructor creates a ed25519Signer object using existing parameters.
506  /// The public key is calculated from the private key.
507  ed25519Signer(const byte x[SECRET_KEYLENGTH]);
508 
509  /// \brief Create a ed25519Signer object
510  /// \param y public key
511  /// \param x private key
512  /// \details This constructor creates a ed25519Signer object using existing parameters.
513  /// \note The public key is not validated.
514  ed25519Signer(const Integer &y, const Integer &x);
515 
516  /// \brief Create a ed25519Signer object
517  /// \param x private key
518  /// \details This constructor creates a ed25519Signer object using existing parameters.
519  /// The public key is calculated from the private key.
520  ed25519Signer(const Integer &x);
521 
522  /// \brief Create a ed25519Signer object
523  /// \param rng RandomNumberGenerator derived class
524  /// \details This constructor creates a new ed25519Signer using the random number generator.
526 
527  /// \brief Create a ed25519Signer object
528  /// \param params public and private key
529  /// \details This constructor creates a ed25519Signer object using existing parameters.
530  /// The <tt>params</tt> can be created with <tt>Save</tt>.
531  /// \note The public key is not validated.
533 
534  // DL_ObjectImplBase
535  PrivateKey& AccessKey() { return m_key; }
536  PrivateKey& AccessPrivateKey() { return m_key; }
537 
538  const PrivateKey& GetKey() const { return m_key; }
539  const PrivateKey& GetPrivateKey() const { return m_key; }
540 
541  // DL_SignatureSchemeBase
542  size_t SignatureLength() const { return SIGNATURE_LENGTH; }
543  size_t MaxRecoverableLength() const { return 0; }
544  size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const {
545  CRYPTOPP_UNUSED(signatureLength); return 0;
546  }
547 
548  bool IsProbabilistic() const { return false; }
549  bool AllowNonrecoverablePart() const { return false; }
550  bool RecoverablePartFirst() const { return false; }
551 
553  return new ed25519_MessageAccumulator(rng);
554  }
555 
556  void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const {
557  CRYPTOPP_UNUSED(messageAccumulator); CRYPTOPP_UNUSED(recoverableMessage);
558  CRYPTOPP_UNUSED(recoverableMessageLength);
559  throw NotImplemented("ed25519Signer: this object does not support recoverable messages");
560  }
561 
562  size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const;
563 
564 protected:
565  ed25519PrivateKey m_key;
566 };
567 
568 // ****************** ed25519 Verifier *********************** //
569 
570 /// \brief Ed25519 public key
571 /// \details ed25519PublicKey is somewhat of a hack. It needed to
572 /// provide DL_PublicKey interface to fit into the existing
573 /// framework, but it lacks a lot of the internals of a true
574 /// DL_PublicKey. The missing pieces include GroupParameters
575 /// and Point, which provide the low level field operations
576 /// found in traditional implementations like NIST curves over
577 /// prime and binary fields.
578 /// \details ed25519PublicKey is also unusual because the
579 /// class members of interest are byte arrays and not Integers.
580 /// In addition, the byte arrays are little-endian meaning
581 /// LSB is at element 0 and the MSB is at element 31.
582 /// If you call \ref ed25519PublicKey::GetPublicElement()
583 /// "GetPublicElement()" then the little-endian byte array is
584 /// converted to a big-endian Integer() so it can be returned
585 /// the way a caller expects. And calling
586 /// \ref ed25519PublicKey::SetPublicElement "SetPublicElement()"
587 /// perfoms a similar internal conversion.
588 /// \since Crypto++ 8.0
590 {
591  /// \brief Size of the public key
592  /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.
593  CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32)
594  typedef Integer Element;
595 
596  OID GetAlgorithmID() const {
597  return m_oid.Empty() ? ASN1::Ed25519() : m_oid;
598  }
599 
600  /// \brief DER encode ASN.1 object
601  /// \param bt BufferedTransformation object
602  /// \details Save() will write the OID associated with algorithm or scheme.
603  /// In the case of public and private keys, this function writes the
604  /// subjectPubicKeyInfo parts.
605  /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
606  /// The default private key format is RFC 5208, which is the old format.
607  /// The old format provides the best interop, and keys will work
608  /// with OpenSSL.
609  void Save(BufferedTransformation &bt) const {
610  BEREncode(bt);
611  }
612 
613  /// \brief BER decode ASN.1 object
614  /// \param bt BufferedTransformation object
615  /// \sa <A HREF="https://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
616  /// Key Packages</A>
618  BERDecode(bt);
619  }
620 
621  // X509PublicKey
623  void DEREncode(BufferedTransformation &bt) const;
624  void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
626 
627  /// \brief Determine if OID is valid for this object
628  /// \details BERDecodeAndCheckAlgorithmID() parses the OID from
629  /// <tt>bt</tt> and determines if it valid for this object. The
630  /// problem in practice is there are multiple OIDs available to
631  /// denote curve25519 operations. The OIDs include an old GNU
632  /// OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves,
633  /// and OIDs specified in draft-ietf-curdle-pkix.
634  /// \details By default BERDecodeAndCheckAlgorithmID() accepts an
635  /// OID set by the user, <tt>ASN1::curve25519()</tt> and <tt>ASN1::Ed25519()</tt>.
636  /// <tt>ASN1::curve25519()</tt> is generic and says "this key is valid for
637  /// curve25519 operations". <tt>ASN1::Ed25519()</tt> is specific and says
638  /// "this key is valid for ed25519 signing."
640 
641  bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
642  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
643  void AssignFrom(const NameValuePairs &source);
644 
645  // DL_PublicKey
646  void SetPublicElement(const byte y[PUBLIC_KEYLENGTH]);
647  void SetPublicElement(const Element &y);
648  const Element& GetPublicElement() const;
649 
650  /// \brief Retrieve public key byte array
651  /// \returns the public key byte array
652  /// \details GetPublicKeyBytePtr() is used by signing code to call ed25519_sign.
653  const byte* GetPublicKeyBytePtr() const {
654  return m_pk.begin();
655  }
656 
657 protected:
659  OID m_oid; // preferred OID
660  mutable Integer m_y; // for DL_PublicKey
661 };
662 
663 /// \brief Ed25519 signature verification algorithm
664 /// \since Crypto++ 8.0
666 {
667  CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32)
668  CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64)
669  typedef Integer Element;
670 
671  virtual ~ed25519Verifier() {}
672 
673  /// \brief Create a ed25519Verifier object
675 
676  /// \brief Create a ed25519Verifier object
677  /// \param y public key
678  /// \details This constructor creates a ed25519Verifier object using existing parameters.
679  /// \note The public key is not validated.
680  ed25519Verifier(const byte y[PUBLIC_KEYLENGTH]);
681 
682  /// \brief Create a ed25519Verifier object
683  /// \param y public key
684  /// \details This constructor creates a ed25519Verifier object using existing parameters.
685  /// \note The public key is not validated.
686  ed25519Verifier(const Integer &y);
687 
688  /// \brief Create a ed25519Verifier object
689  /// \param params public and private key
690  /// \details This constructor creates a ed25519Verifier object using existing parameters.
691  /// The <tt>params</tt> can be created with <tt>Save</tt>.
692  /// \note The public key is not validated.
694 
695  /// \brief Create a ed25519Verifier object
696  /// \param signer ed25519 signer object
697  /// \details This constructor creates a ed25519Verifier object using existing parameters.
698  /// The <tt>params</tt> can be created with <tt>Save</tt>.
699  /// \note The public key is not validated.
700  ed25519Verifier(const ed25519Signer& signer);
701 
702  // DL_ObjectImplBase
703  PublicKey& AccessKey() { return m_key; }
704  PublicKey& AccessPublicKey() { return m_key; }
705 
706  const PublicKey& GetKey() const { return m_key; }
707  const PublicKey& GetPublicKey() const { return m_key; }
708 
709  // DL_SignatureSchemeBase
710  size_t SignatureLength() const { return SIGNATURE_LENGTH; }
711  size_t MaxRecoverableLength() const { return 0; }
712  size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const {
713  CRYPTOPP_UNUSED(signatureLength); return 0;
714  }
715 
716  bool IsProbabilistic() const { return false; }
717  bool AllowNonrecoverablePart() const { return false; }
718  bool RecoverablePartFirst() const { return false; }
719 
721  return new ed25519_MessageAccumulator;
722  }
723 
724  void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const {
725  CRYPTOPP_ASSERT(signature != NULLPTR);
726  CRYPTOPP_ASSERT(signatureLength == SIGNATURE_LENGTH);
727  ed25519_MessageAccumulator& accum = static_cast<ed25519_MessageAccumulator&>(messageAccumulator);
728  if (signature && signatureLength)
729  std::memcpy(accum.signature(), signature, STDMIN((size_t)SIGNATURE_LENGTH, signatureLength));
730  }
731 
732  bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
733 
734  DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const {
735  CRYPTOPP_UNUSED(recoveredMessage); CRYPTOPP_UNUSED(messageAccumulator);
736  throw NotImplemented("ed25519Verifier: this object does not support recoverable messages");
737  }
738 
739 protected:
740  ed25519PublicKey m_key;
741 };
742 
743 /// \brief Ed25519 signature scheme
744 /// \since Crypto++ 8.0
745 struct ed25519
746 {
747  typedef ed25519Signer Signer;
748  typedef ed25519Verifier Verifier;
749 };
750 
751 NAMESPACE_END // CryptoPP
752 
753 #endif // CRYPTOPP_XED25519_H
x25519 with key validation
Definition: xed25519.h:54
static const int SECRET_KEYLENGTH
Size of the private key.
Definition: xed25519.h:480
void Save(BufferedTransformation &bt) const
DER encode ASN.1 object.
Definition: xed25519.h:367
static const int SHARED_KEYLENGTH
Size of the shared key.
Definition: xed25519.h:65
unsigned int PublicKeyLength() const
Provides the size of the public key.
Definition: xed25519.h:232
Ed25519 private key.
Definition: xed25519.h:332
void Save(BufferedTransformation &bt, bool v1) const
DER encode ASN.1 object.
Definition: xed25519.h:386
void Load(BufferedTransformation &bt)
BER decode ASN.1 object.
Definition: xed25519.h:617
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition: xed25519.cpp:315
bool IsProbabilistic() const
Determines whether a signature scheme requires a random number generator.
Definition: xed25519.h:716
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.h:194
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
Check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
Definition: xed25519.cpp:807
void ClampKeys(byte y[PUBLIC_KEYLENGTH], byte x[SECRET_KEYLENGTH]) const
Clamp a private key.
Definition: xed25519.cpp:110
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
Recover a message from its signature.
Definition: xed25519.h:734
This file contains helper classes/functions for implementing public key algorithms.
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:771
size_t MaxRecoverableLength() const
Provides the length of longest message that can be recovered.
Definition: xed25519.h:543
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
Definition: xed25519.h:653
static const int SIGNATURE_LENGTH
Size of the siganture.
Definition: xed25519.h:344
Encodes and Decodes privateKeyInfo.
Definition: asn.h:421
Ed25519 signature verification algorithm.
Definition: xed25519.h:665
Interface for public-key signers.
Definition: cryptlib.h:2727
void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
Definition: xed25519.cpp:727
Abstract base classes that provide a uniform interface to this library.
void Update(const byte *msg, size_t len)
Add data to the accumulator.
Definition: xed25519.h:273
bool AllowNonrecoverablePart() const
Determines whether the non-recoverable message part can be signed.
Definition: xed25519.h:549
ASN.1 object identifiers for algorthms and schemes.
bool IsProbabilistic() const
Determines whether a signature scheme requires a random number generator.
Definition: xed25519.h:548
bool AllowNonrecoverablePart() const
Determines whether the non-recoverable message part can be signed.
Definition: xed25519.h:717
void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
Input signature into a message accumulator.
Definition: xed25519.h:724
void Restart()
Reset the accumulator.
Definition: xed25519.h:279
size_t size() const
Retrieve size of data buffer.
Definition: xed25519.h:304
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate a public key from a private key in this domain.
Definition: xed25519.cpp:332
STL namespace.
Interface for random number generators.
Definition: cryptlib.h:1349
void MakePublicKey(PublicKey &pub) const
Initializes a public key from this key.
Definition: xed25519.cpp:435
ed25519Verifier()
Create a ed25519Verifier object.
Definition: xed25519.h:674
static const int SECRET_KEYLENGTH
Size of the private key.
Definition: xed25519.h:59
void DEREncodePublicKey(BufferedTransformation &bt) const
encode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
Definition: xed25519.cpp:745
Interface for buffered transformations.
Definition: cryptlib.h:1564
Interface for private keys.
Definition: cryptlib.h:2396
OID GetAlgorithmID() const
Retrieves the OID of the algorithm.
Definition: xed25519.h:596
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.cpp:714
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:369
size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
Provides the length of longest message that can be recovered from a signature of given length...
Definition: xed25519.h:544
PublicKey & AccessPublicKey()
Retrieves a reference to a Public Key.
Definition: xed25519.h:704
const PublicKey & GetPublicKey() const
Retrieves a reference to a Public Key.
Definition: xed25519.h:707
void ClampKeys(byte y[PUBLIC_KEYLENGTH], byte x[SECRET_KEYLENGTH]) const
Clamp a private key.
Definition: xed25519.cpp:351
bool IsClamped(const byte x[SECRET_KEYLENGTH]) const
Determine if private key is clamped.
Definition: xed25519.cpp:358
static const int PUBLIC_KEYLENGTH
Size of the public key.
Definition: xed25519.h:339
Interface for domains of simple key agreement protocols.
Definition: cryptlib.h:2863
const byte * signature() const
Retrieve pointer to signature buffer.
Definition: xed25519.h:292
Returns a decoding results.
Definition: cryptlib.h:255
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:457
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate private key in this domain.
Definition: xed25519.cpp:326
const byte * data() const
Retrieve pointer to data buffer.
Definition: xed25519.h:298
A method was called which was not implemented.
Definition: cryptlib.h:223
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:700
void SetAlgorithmID(const OID &oid)
Set the Object Identifier
Definition: xed25519.h:138
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:363
static const int PUBLIC_KEYLENGTH
Size of the public key.
Definition: xed25519.h:483
bool RecoverablePartFirst() const
Determines whether the recoverable part must be input before the non-recoverable part.
Definition: xed25519.h:718
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:266
static const int PUBLIC_KEYLENGTH
Size of the public key.
Definition: xed25519.h:62
unsigned int PrivateKeyLength() const
Provides the size of the private key.
Definition: xed25519.h:231
Multiple precision integer with arithmetic operations.
Definition: integer.h:49
size_t SignatureLength() const
Provides the signature length if it only depends on the key.
Definition: xed25519.h:710
const PrivateKey & GetPrivateKey() const
Retrieves a reference to a Private Key.
Definition: xed25519.h:539
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.h:404
void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
Input a recoverable message to an accumulator.
Definition: xed25519.h:556
bool RecoverablePartFirst() const
Determines whether the recoverable part must be input before the non-recoverable part.
Definition: xed25519.h:550
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:154
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:398
PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
Create a new HashTransformation to accumulate the message to be signed.
Definition: xed25519.h:552
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode privateKey part of privateKeyInfo, without the OCTET STRING header
Definition: xed25519.cpp:223
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:563
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:60
void Save(BufferedTransformation &bt, bool v1) const
DER encode ASN.1 object.
Definition: xed25519.h:180
static const int SECRET_KEYLENGTH
Size of the private key.
Definition: xed25519.h:336
ed25519 message accumulator
Definition: xed25519.h:253
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:766
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:252
Ed25519 signature algorithm.
Definition: xed25519.h:476
Interface for accumulating messages to be signed or verified.
Definition: cryptlib.h:2711
ed25519_MessageAccumulator(RandomNumberGenerator &rng)
Create a message accumulator.
Definition: xed25519.h:266
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
Sign and restart messageAccumulator.
Definition: xed25519.cpp:631
bool IsClamped(const byte x[SECRET_KEYLENGTH]) const
Determine if private key is clamped.
Definition: xed25519.cpp:116
void Save(BufferedTransformation &bt) const
DER encode ASN.1 object.
Definition: xed25519.h:161
bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
Test if a key has small order.
Definition: xed25519.cpp:121
Interface for public-key signature verifiers.
Definition: cryptlib.h:2791
CryptoParameters & AccessCryptoParameters()
Retrieves a reference to Crypto Parameters.
Definition: xed25519.h:148
x25519(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH])
Create a x25519 object.
Definition: xed25519.cpp:56
OID GetAlgorithmID() const
Get the Object Identifier
Definition: xed25519.h:132
void Load(BufferedTransformation &bt)
BER decode ASN.1 object.
Definition: xed25519.h:394
size_t MaxRecoverableLength() const
Provides the length of longest message that can be recovered.
Definition: xed25519.h:711
void Save(BufferedTransformation &bt) const
DER encode ASN.1 object.
Definition: xed25519.h:609
PrivateKey & AccessPrivateKey()
Retrieves a reference to a Private Key.
Definition: xed25519.h:536
Interface for crypto prameters.
Definition: cryptlib.h:2401
size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const
Provides the length of longest message that can be recovered from a signature of given length...
Definition: xed25519.h:712
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:670
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:442
Interface for public keys.
Definition: cryptlib.h:2391
Crypto++ library namespace.
Encodes and decodes subjectPublicKeyInfo.
Definition: asn.h:398
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
Derive agreed value.
Definition: xed25519.cpp:338
ed25519Signer()
Create a ed25519Signer object.
Definition: xed25519.h:494
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode privateKey part of privateKeyInfo, without the OCTET STRING header
Definition: xed25519.cpp:525
const byte * GetPrivateKeyBytePtr() const
Retrieve private key byte array.
Definition: xed25519.h:456
virtual void BEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: cryptlib.h:3153
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition: xed25519.cpp:423
unsigned int AgreedValueLength() const
Provides the size of the agreed value.
Definition: xed25519.h:230
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:648
OID GetAlgorithmID() const
Retrieves the OID of the algorithm.
Definition: xed25519.h:352
Ed25519 public key.
Definition: xed25519.h:589
static const int SIGNATURE_LENGTH
Size of the siganture.
Definition: xed25519.h:488
Ed25519 signature scheme.
Definition: xed25519.h:745
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:295
void DEREncodePrivateKey(BufferedTransformation &bt) const
encode privateKey part of privateKeyInfo, without the OCTET STRING header
Definition: xed25519.cpp:546
Object Identifier.
Definition: asn.h:166
static const int PUBLIC_KEYLENGTH
Size of the public key.
Definition: xed25519.h:593
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:139
size_t SignatureLength() const
Provides the signature length if it only depends on the key.
Definition: xed25519.h:542
void DEREncodePrivateKey(BufferedTransformation &bt) const
encode privateKey part of privateKeyInfo, without the OCTET STRING header
Definition: xed25519.cpp:244
void Load(BufferedTransformation &bt)
BER decode ASN.1 object.
Definition: xed25519.h:188
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
Definition: xed25519.h:463
ed25519_MessageAccumulator * NewVerificationAccumulator() const
Create a new HashTransformation to accumulate the message to be verified.
Definition: xed25519.h:720
byte * signature()
Retrieve pointer to signature buffer.
Definition: xed25519.h:286
Interface for retrieving values given their names.
Definition: cryptlib.h:293
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:685