Crypto++  8.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 Test if a key has small order
454  /// \param y public key
455  bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const;
456 
457  /// \brief Retrieve private key byte array
458  /// \returns the private key byte array
459  /// \details GetPrivateKeyBytePtr() is used by signing code to call ed25519_sign.
460  const byte* GetPrivateKeyBytePtr() const {
461  return m_sk.begin();
462  }
463 
464  /// \brief Retrieve public key byte array
465  /// \returns the public key byte array
466  /// \details GetPublicKeyBytePtr() is used by signing code to call ed25519_sign.
467  const byte* GetPublicKeyBytePtr() const {
468  return m_pk.begin();
469  }
470 
471 protected:
474  OID m_oid; // preferred OID
475  mutable Integer m_x; // for DL_PrivateKey
476 };
477 
478 /// \brief Ed25519 signature algorithm
479 /// \since Crypto++ 8.0
480 struct ed25519Signer : public PK_Signer
481 {
482  /// \brief Size of the private key
483  /// \details SECRET_KEYLENGTH is the size of the private key, in bytes.
484  CRYPTOPP_CONSTANT(SECRET_KEYLENGTH = 32)
485  /// \brief Size of the public key
486  /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.
487  CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32)
488  /// \brief Size of the siganture
489  /// \details SIGNATURE_LENGTH is the size of the signature, in bytes.
490  /// ed25519 is a DL-based signature scheme. The signature is the
491  /// concatenation of <tt>r || s</tt>.
492  CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64)
493  typedef Integer Element;
494 
495  virtual ~ed25519Signer() {}
496 
497  /// \brief Create a ed25519Signer object
499 
500  /// \brief Create a ed25519Signer object
501  /// \param y public key
502  /// \param x private key
503  /// \details This constructor creates a ed25519Signer object using existing parameters.
504  /// \note The public key is not validated.
505  ed25519Signer(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]);
506 
507  /// \brief Create a ed25519Signer object
508  /// \param x private key
509  /// \details This constructor creates a ed25519Signer object using existing parameters.
510  /// The public key is calculated from the private key.
511  ed25519Signer(const byte x[SECRET_KEYLENGTH]);
512 
513  /// \brief Create a ed25519Signer object
514  /// \param y public key
515  /// \param x private key
516  /// \details This constructor creates a ed25519Signer object using existing parameters.
517  /// \note The public key is not validated.
518  ed25519Signer(const Integer &y, const Integer &x);
519 
520  /// \brief Create a ed25519Signer object
521  /// \param x private key
522  /// \details This constructor creates a ed25519Signer object using existing parameters.
523  /// The public key is calculated from the private key.
524  ed25519Signer(const Integer &x);
525 
526  /// \brief Create a ed25519Signer object
527  /// \param rng RandomNumberGenerator derived class
528  /// \details This constructor creates a new ed25519Signer using the random number generator.
530 
531  /// \brief Create a ed25519Signer object
532  /// \param params public and private key
533  /// \details This constructor creates a ed25519Signer object using existing parameters.
534  /// The <tt>params</tt> can be created with <tt>Save</tt>.
535  /// \note The public key is not validated.
537 
538  // DL_ObjectImplBase
539  PrivateKey& AccessKey() { return m_key; }
540  PrivateKey& AccessPrivateKey() { return m_key; }
541 
542  const PrivateKey& GetKey() const { return m_key; }
543  const PrivateKey& GetPrivateKey() const { return m_key; }
544 
545  // DL_SignatureSchemeBase
546  size_t SignatureLength() const { return SIGNATURE_LENGTH; }
547  size_t MaxRecoverableLength() const { return 0; }
548  size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const {
549  CRYPTOPP_UNUSED(signatureLength); return 0;
550  }
551 
552  bool IsProbabilistic() const { return false; }
553  bool AllowNonrecoverablePart() const { return false; }
554  bool RecoverablePartFirst() const { return false; }
555 
557  return new ed25519_MessageAccumulator(rng);
558  }
559 
560  void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const {
561  CRYPTOPP_UNUSED(messageAccumulator); CRYPTOPP_UNUSED(recoverableMessage);
562  CRYPTOPP_UNUSED(recoverableMessageLength);
563  throw NotImplemented("ed25519Signer: this object does not support recoverable messages");
564  }
565 
566  size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const;
567 
568 protected:
569  ed25519PrivateKey m_key;
570 };
571 
572 // ****************** ed25519 Verifier *********************** //
573 
574 /// \brief Ed25519 public key
575 /// \details ed25519PublicKey is somewhat of a hack. It needed to
576 /// provide DL_PublicKey interface to fit into the existing
577 /// framework, but it lacks a lot of the internals of a true
578 /// DL_PublicKey. The missing pieces include GroupParameters
579 /// and Point, which provide the low level field operations
580 /// found in traditional implementations like NIST curves over
581 /// prime and binary fields.
582 /// \details ed25519PublicKey is also unusual because the
583 /// class members of interest are byte arrays and not Integers.
584 /// In addition, the byte arrays are little-endian meaning
585 /// LSB is at element 0 and the MSB is at element 31.
586 /// If you call \ref ed25519PublicKey::GetPublicElement()
587 /// "GetPublicElement()" then the little-endian byte array is
588 /// converted to a big-endian Integer() so it can be returned
589 /// the way a caller expects. And calling
590 /// \ref ed25519PublicKey::SetPublicElement "SetPublicElement()"
591 /// perfoms a similar internal conversion.
592 /// \since Crypto++ 8.0
594 {
595  /// \brief Size of the public key
596  /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.
597  CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32)
598  typedef Integer Element;
599 
600  OID GetAlgorithmID() const {
601  return m_oid.Empty() ? ASN1::Ed25519() : m_oid;
602  }
603 
604  /// \brief DER encode ASN.1 object
605  /// \param bt BufferedTransformation object
606  /// \details Save() will write the OID associated with algorithm or scheme.
607  /// In the case of public and private keys, this function writes the
608  /// subjectPubicKeyInfo parts.
609  /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
610  /// The default private key format is RFC 5208, which is the old format.
611  /// The old format provides the best interop, and keys will work
612  /// with OpenSSL.
613  void Save(BufferedTransformation &bt) const {
614  BEREncode(bt);
615  }
616 
617  /// \brief BER decode ASN.1 object
618  /// \param bt BufferedTransformation object
619  /// \sa <A HREF="https://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
620  /// Key Packages</A>
622  BERDecode(bt);
623  }
624 
625  // X509PublicKey
627  void DEREncode(BufferedTransformation &bt) const;
628  void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
629  void DEREncodePublicKey(BufferedTransformation &bt) const;
630 
631  /// \brief Determine if OID is valid for this object
632  /// \details BERDecodeAndCheckAlgorithmID() parses the OID from
633  /// <tt>bt</tt> and determines if it valid for this object. The
634  /// problem in practice is there are multiple OIDs available to
635  /// denote curve25519 operations. The OIDs include an old GNU
636  /// OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves,
637  /// and OIDs specified in draft-ietf-curdle-pkix.
638  /// \details By default BERDecodeAndCheckAlgorithmID() accepts an
639  /// OID set by the user, <tt>ASN1::curve25519()</tt> and <tt>ASN1::Ed25519()</tt>.
640  /// <tt>ASN1::curve25519()</tt> is generic and says "this key is valid for
641  /// curve25519 operations". <tt>ASN1::Ed25519()</tt> is specific and says
642  /// "this key is valid for ed25519 signing."
644 
645  bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
646  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
647  void AssignFrom(const NameValuePairs &source);
648 
649  // DL_PublicKey
650  void SetPublicElement(const byte y[PUBLIC_KEYLENGTH]);
651  void SetPublicElement(const Element &y);
652  const Element& GetPublicElement() const;
653 
654  /// \brief Retrieve public key byte array
655  /// \returns the public key byte array
656  /// \details GetPublicKeyBytePtr() is used by signing code to call ed25519_sign.
657  const byte* GetPublicKeyBytePtr() const {
658  return m_pk.begin();
659  }
660 
661 protected:
663  OID m_oid; // preferred OID
664  mutable Integer m_y; // for DL_PublicKey
665 };
666 
667 /// \brief Ed25519 signature verification algorithm
668 /// \since Crypto++ 8.0
670 {
671  CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32)
672  CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64)
673  typedef Integer Element;
674 
675  virtual ~ed25519Verifier() {}
676 
677  /// \brief Create a ed25519Verifier object
679 
680  /// \brief Create a ed25519Verifier object
681  /// \param y public key
682  /// \details This constructor creates a ed25519Verifier object using existing parameters.
683  /// \note The public key is not validated.
684  ed25519Verifier(const byte y[PUBLIC_KEYLENGTH]);
685 
686  /// \brief Create a ed25519Verifier object
687  /// \param y public key
688  /// \details This constructor creates a ed25519Verifier object using existing parameters.
689  /// \note The public key is not validated.
690  ed25519Verifier(const Integer &y);
691 
692  /// \brief Create a ed25519Verifier object
693  /// \param params public and private key
694  /// \details This constructor creates a ed25519Verifier object using existing parameters.
695  /// The <tt>params</tt> can be created with <tt>Save</tt>.
696  /// \note The public key is not validated.
698 
699  /// \brief Create a ed25519Verifier object
700  /// \param signer ed25519 signer object
701  /// \details This constructor creates a ed25519Verifier object using existing parameters.
702  /// The <tt>params</tt> can be created with <tt>Save</tt>.
703  /// \note The public key is not validated.
704  ed25519Verifier(const ed25519Signer& signer);
705 
706  // DL_ObjectImplBase
707  PublicKey& AccessKey() { return m_key; }
708  PublicKey& AccessPublicKey() { return m_key; }
709 
710  const PublicKey& GetKey() const { return m_key; }
711  const PublicKey& GetPublicKey() const { return m_key; }
712 
713  // DL_SignatureSchemeBase
714  size_t SignatureLength() const { return SIGNATURE_LENGTH; }
715  size_t MaxRecoverableLength() const { return 0; }
716  size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const {
717  CRYPTOPP_UNUSED(signatureLength); return 0;
718  }
719 
720  bool IsProbabilistic() const { return false; }
721  bool AllowNonrecoverablePart() const { return false; }
722  bool RecoverablePartFirst() const { return false; }
723 
725  return new ed25519_MessageAccumulator;
726  }
727 
728  void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const {
729  CRYPTOPP_ASSERT(signature != NULLPTR);
730  CRYPTOPP_ASSERT(signatureLength == SIGNATURE_LENGTH);
731  ed25519_MessageAccumulator& accum = static_cast<ed25519_MessageAccumulator&>(messageAccumulator);
732  if (signature && signatureLength)
733  std::memcpy(accum.signature(), signature, STDMIN((size_t)SIGNATURE_LENGTH, signatureLength));
734  }
735 
736  bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
737 
738  DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const {
739  CRYPTOPP_UNUSED(recoveredMessage); CRYPTOPP_UNUSED(messageAccumulator);
740  throw NotImplemented("ed25519Verifier: this object does not support recoverable messages");
741  }
742 
743 protected:
744  ed25519PublicKey m_key;
745 };
746 
747 /// \brief Ed25519 signature scheme
748 /// \since Crypto++ 8.0
749 struct ed25519
750 {
751  typedef ed25519Signer Signer;
752  typedef ed25519Verifier Verifier;
753 };
754 
755 NAMESPACE_END // CryptoPP
756 
757 #endif // CRYPTOPP_XED25519_H
x25519 with key validation
Definition: xed25519.h:54
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:621
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition: xed25519.cpp:332
bool IsProbabilistic() const
Determines whether a signature scheme requires a random number generator.
Definition: xed25519.h:720
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.h:194
void ClampKeys(byte y[PUBLIC_KEYLENGTH], byte x[SECRET_KEYLENGTH]) const
Clamp a private key.
Definition: xed25519.cpp:128
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
Recover a message from its signature.
Definition: xed25519.h:738
This file contains helper classes/functions for implementing public key algorithms.
size_t MaxRecoverableLength() const
Provides the length of longest message that can be recovered.
Definition: xed25519.h:547
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
Definition: xed25519.h:657
Encodes and Decodes privateKeyInfo.
Definition: asn.h:421
Ed25519 signature verification algorithm.
Definition: xed25519.h:669
Interface for public-key signers.
Definition: cryptlib.h:2727
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:553
ASN.1 object identifiers for algorthms and schemes.
bool IsProbabilistic() const
Determines whether a signature scheme requires a random number generator.
Definition: xed25519.h:552
bool AllowNonrecoverablePart() const
Determines whether the non-recoverable message part can be signed.
Definition: xed25519.h:721
void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
Input signature into a message accumulator.
Definition: xed25519.h:728
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:349
STL namespace.
Interface for random number generators.
Definition: cryptlib.h:1349
ed25519Verifier()
Create a ed25519Verifier object.
Definition: xed25519.h:678
static const int SECRET_KEYLENGTH
Size of the private key.
Definition: xed25519.h:59
Interface for buffered transformations.
Definition: cryptlib.h:1564
Interface for private keys.
Definition: cryptlib.h:2396
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:548
PublicKey & AccessPublicKey()
Retrieves a reference to a Public Key.
Definition: xed25519.h:708
const PublicKey & GetPublicKey() const
Retrieves a reference to a Public Key.
Definition: xed25519.h:711
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 GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate private key in this domain.
Definition: xed25519.cpp:343
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 SetAlgorithmID(const OID &oid)
Set the Object Identifier
Definition: xed25519.h:138
bool RecoverablePartFirst() const
Determines whether the recoverable part must be input before the non-recoverable part.
Definition: xed25519.h:722
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:283
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:714
const PrivateKey & GetPrivateKey() const
Retrieves a reference to a Private Key.
Definition: xed25519.h:543
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:560
bool RecoverablePartFirst() const
Determines whether the recoverable part must be input before the non-recoverable part.
Definition: xed25519.h:554
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:159
PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
Create a new HashTransformation to accumulate the message to be signed.
Definition: xed25519.h:556
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode privateKey part of privateKeyInfo, without the OCTET STRING header
Definition: xed25519.cpp:231
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
ed25519 message accumulator
Definition: xed25519.h:253
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:260
Ed25519 signature algorithm.
Definition: xed25519.h:480
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
bool IsClamped(const byte x[SECRET_KEYLENGTH]) const
Determine if private key is clamped.
Definition: xed25519.cpp:134
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:139
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:74
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:715
void Save(BufferedTransformation &bt) const
DER encode ASN.1 object.
Definition: xed25519.h:613
PrivateKey & AccessPrivateKey()
Retrieves a reference to a Private Key.
Definition: xed25519.h:540
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:716
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:355
ed25519Signer()
Create a ed25519Signer object.
Definition: xed25519.h:498
const byte * GetPrivateKeyBytePtr() const
Retrieve private key byte array.
Definition: xed25519.h:460
virtual void BEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: cryptlib.h:3153
unsigned int AgreedValueLength() const
Provides the size of the agreed value.
Definition: xed25519.h:230
Ed25519 public key.
Definition: xed25519.h:593
Ed25519 signature scheme.
Definition: xed25519.h:749
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:312
Object Identifier.
Definition: asn.h:166
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:144
size_t SignatureLength() const
Provides the signature length if it only depends on the key.
Definition: xed25519.h:546
void DEREncodePrivateKey(BufferedTransformation &bt) const
encode privateKey part of privateKeyInfo, without the OCTET STRING header
Definition: xed25519.cpp:252
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:467
ed25519_MessageAccumulator * NewVerificationAccumulator() const
Create a new HashTransformation to accumulate the message to be verified.
Definition: xed25519.h:724
byte * signature()
Retrieve pointer to signature buffer.
Definition: xed25519.h:286
Interface for retrieving values given their names.
Definition: cryptlib.h:293