Crypto++  8.2
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 // http://github.com/floodyberry/curve25519-donna and
5 // http://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 /// "http:///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="http://github.com/floodyberry/curve25519-donna">curve25519-donna</A>,
32 /// ed22519 GitHub <A
33 /// HREF="http://github.com/floodyberry/ed25519-donna">ed25519-donna</A>, and
34 /// <A HREF="http:///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  /// \details This constructor creates an empty x25519 object. It is
71  /// intended for use in loading existing parameters, like CryptoBox
72  /// parameters. If you are perfoming key agreement you should use a
73  /// constructor that generates random parameters on construction.
74  x25519() {}
75 
76  /// \brief Create a x25519 object
77  /// \param y public key
78  /// \param x private key
79  /// \details This constructor creates a x25519 object using existing parameters.
80  /// \note The public key is not validated.
81  x25519(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]);
82 
83  /// \brief Create a x25519 object
84  /// \param x private key
85  /// \details This constructor creates a x25519 object using existing parameters.
86  /// The public key is calculated from the private key.
87  x25519(const byte x[SECRET_KEYLENGTH]);
88 
89  /// \brief Create a x25519 object
90  /// \param y public key
91  /// \param x private key
92  /// \details This constructor creates a x25519 object using existing parameters.
93  /// \note The public key is not validated.
94  x25519(const Integer &y, const Integer &x);
95 
96  /// \brief Create a x25519 object
97  /// \param x private key
98  /// \details This constructor creates a x25519 object using existing parameters.
99  /// The public key is calculated from the private key.
100  x25519(const Integer &x);
101 
102  /// \brief Create a x25519 object
103  /// \param rng RandomNumberGenerator derived class
104  /// \details This constructor creates a new x25519 using the random number generator.
106 
107  /// \brief Create a x25519 object
108  /// \param params public and private key
109  /// \details This constructor creates a x25519 object using existing parameters.
110  /// The <tt>params</tt> can be created with <tt>Save</tt>.
111  /// \note The public key is not validated.
113 
114  /// \brief Create a x25519 object
115  /// \param oid an object identifier
116  /// \details This constructor creates a new x25519 using the specified OID. The public
117  /// and private points are uninitialized.
118  x25519(const OID &oid);
119 
120  /// \brief Clamp a private key
121  /// \param x private key
122  /// \details ClampKeys() clamps a private key and then regenerates the
123  /// public key from the private key.
124  void ClampKey(byte x[SECRET_KEYLENGTH]) const;
125 
126  /// \brief Determine if private key is clamped
127  /// \param x private key
128  bool IsClamped(const byte x[SECRET_KEYLENGTH]) const;
129 
130  /// \brief Test if a key has small order
131  /// \param y public key
132  bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const;
133 
134  /// \brief Get the Object Identifier
135  /// \return the Object Identifier
136  /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
137  /// The default private key format is RFC 5208.
138  OID GetAlgorithmID() const {
139  return m_oid.Empty() ? ASN1::X25519() : m_oid;
140  }
141 
142  /// \brief Set the Object Identifier
143  /// \param oid the new Object Identifier
144  void SetAlgorithmID(const OID& oid) {
145  m_oid = oid;
146  }
147 
148  // CryptoParameters
149  bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
150  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
151  void AssignFrom(const NameValuePairs &source);
152 
153  // CryptoParameters
155 
156  /// \brief DER encode ASN.1 object
157  /// \param bt BufferedTransformation object
158  /// \details Save() will write the OID associated with algorithm or scheme.
159  /// In the case of public and private keys, this function writes the
160  /// subjectPubicKeyInfo parts.
161  /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
162  /// The default private key format is RFC 5208, which is the old format.
163  /// The old format provides the best interop, and keys will work
164  /// with OpenSSL.
165  /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
166  /// Key Packages</A>
167  void Save(BufferedTransformation &bt) const {
168  DEREncode(bt, 0);
169  }
170 
171  /// \brief DER encode ASN.1 object
172  /// \param bt BufferedTransformation object
173  /// \param v1 flag indicating v1
174  /// \details Save() will write the OID associated with algorithm or scheme.
175  /// In the case of public and private keys, this function writes the
176  /// subjectPubicKeyInfo parts.
177  /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
178  /// The default private key format is RFC 5208.
179  /// \details v1 means INTEGER 0 is written. INTEGER 0 means
180  /// RFC 5208 format, which is the old format. The old format provides
181  /// the best interop, and keys will work with OpenSSL. The other
182  /// option uses INTEGER 1. INTEGER 1 means RFC 5958 format,
183  /// which is the new format.
184  /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
185  /// Key Packages</A>
186  void Save(BufferedTransformation &bt, bool v1) const {
187  DEREncode(bt, v1 ? 0 : 1);
188  }
189 
190  /// \brief BER decode ASN.1 object
191  /// \param bt BufferedTransformation object
192  /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
193  /// Key Packages</A>
195  BERDecode(bt);
196  }
197 
198  // PKCS8PrivateKey
200  void DEREncode(BufferedTransformation &bt) const { DEREncode(bt, 0); }
201  void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
203 
204  /// \brief DER encode ASN.1 object
205  /// \param bt BufferedTransformation object
206  /// \param version indicates version
207  /// \details DEREncode() will write the OID associated with algorithm or
208  /// scheme. In the case of public and private keys, this function writes
209  /// the subjectPubicKeyInfo parts.
210  /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
211  /// The default private key format is RFC 5208.
212  /// \details The value of version is written as the INTEGER. INTEGER 0 means
213  /// RFC 5208 format, which is the old format. The old format provides
214  /// the best interop, and keys will work with OpenSSL. The INTEGER 1
215  /// means RFC 5958 format, which is the new format.
216  void DEREncode(BufferedTransformation &bt, int version) const;
217 
218  /// \brief Determine if OID is valid for this object
219  /// \details BERDecodeAndCheckAlgorithmID() parses the OID from
220  /// <tt>bt</tt> and determines if it valid for this object. The
221  /// problem in practice is there are multiple OIDs available to
222  /// denote curve25519 operations. The OIDs include an old GNU
223  /// OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves,
224  /// and OIDs specified in draft-ietf-curdle-pkix.
225  /// \details By default BERDecodeAndCheckAlgorithmID() accepts an
226  /// OID set by the user, <tt>ASN1::curve25519()</tt> and <tt>ASN1::X25519()</tt>.
227  /// <tt>ASN1::curve25519()</tt> is generic and says "this key is valid for
228  /// curve25519 operations". <tt>ASN1::X25519()</tt> is specific and says
229  /// "this key is valid for x25519 key exchange."
231 
232  // DL_PrivateKey
233  void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params);
234 
235  // SimpleKeyAgreementDomain
236  unsigned int AgreedValueLength() const {return SHARED_KEYLENGTH;}
237  unsigned int PrivateKeyLength() const {return SECRET_KEYLENGTH;}
238  unsigned int PublicKeyLength() const {return PUBLIC_KEYLENGTH;}
239 
240  // SimpleKeyAgreementDomain
241  void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const;
242  void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const;
243  bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const;
244 
245 protected:
246  // Create a public key from a private key
247  void SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const;
248 
249 protected:
252  OID m_oid; // preferred OID
253 };
254 
255 // ****************** ed25519 Signer *********************** //
256 
257 /// \brief ed25519 message accumulator
258 /// \details ed25519 buffers the entire message, and does not
259 /// digest the message incrementally. You should be careful with
260 /// large messages like files on-disk. The behavior is by design
261 /// because Bernstein feels small messages should be authenticated;
262 /// and larger messages will be digested by the application.
263 /// \details The accumulator is used for signing and verification.
264 /// The first 64-bytes of storage is reserved for the signature.
265 /// During signing the signature storage is unused. During
266 /// verification the first 64 bytes holds the signature. The
267 /// signature is provided by the PK_Verifier framework and the
268 /// call to PK_Signer::InputSignature. Member functions data()
269 /// and size() refer to the accumulated message. Member function
270 /// signature() refers to the signature with an implicit size of
271 /// SIGNATURE_LENGTH bytes.
272 /// \details Applications which digest large messages, like an ISO
273 /// disk file, should take care because the design effectively
274 /// disgorges the format operation from the signing operation.
275 /// Put another way, be careful to ensure what you are signing is
276 /// is in fact a digest of the intended message, and not a different
277 /// message digest supplied by an attacker.
279 {
280  CRYPTOPP_CONSTANT(RESERVE_SIZE=2048+64);
281  CRYPTOPP_CONSTANT(SIGNATURE_LENGTH=64);
282 
283  /// \brief Create a message accumulator
285  Restart();
286  }
287 
288  /// \brief Create a message accumulator
289  /// \details ed25519 does not use a RNG. You can safely use
290  /// NullRNG() because IsProbablistic returns false.
292  CRYPTOPP_UNUSED(rng); Restart();
293  }
294 
295  /// \brief Add data to the accumulator
296  /// \param msg pointer to the data to accumulate
297  /// \param len the size of the data, in bytes
298  void Update(const byte* msg, size_t len) {
299  if (msg && len)
300  m_msg.insert(m_msg.end(), msg, msg+len);
301  }
302 
303  /// \brief Reset the accumulator
304  void Restart() {
305  m_msg.reserve(RESERVE_SIZE);
306  m_msg.resize(SIGNATURE_LENGTH);
307  }
308 
309  /// \brief Retrieve pointer to signature buffer
310  /// \return pointer to signature buffer
311  byte* signature() {
312  return &m_msg[0];
313  }
314 
315  /// \brief Retrieve pointer to signature buffer
316  /// \return pointer to signature buffer
317  const byte* signature() const {
318  return &m_msg[0];
319  }
320 
321  /// \brief Retrieve pointer to data buffer
322  /// \return pointer to data buffer
323  const byte* data() const {
324  return &m_msg[0]+SIGNATURE_LENGTH;
325  }
326 
327  /// \brief Retrieve size of data buffer
328  /// \return size of the data buffer, in bytes
329  size_t size() const {
330  return m_msg.size()-SIGNATURE_LENGTH;
331  }
332 
333 protected:
334  // TODO: Find an equivalent Crypto++ structure.
335  std::vector<byte, AllocatorWithCleanup<byte> > m_msg;
336 };
337 
338 /// \brief Ed25519 private key
339 /// \details ed25519PrivateKey is somewhat of a hack. It needed to
340 /// provide DL_PrivateKey interface to fit into the existing
341 /// framework, but it lacks a lot of the internals of a true
342 /// DL_PrivateKey. The missing pieces include GroupParameters
343 /// and Point, which provide the low level field operations
344 /// found in traditional implementations like NIST curves over
345 /// prime and binary fields.
346 /// \details ed25519PrivateKey is also unusual because the
347 /// class members of interest are byte arrays and not Integers.
348 /// In addition, the byte arrays are little-endian meaning
349 /// LSB is at element 0 and the MSB is at element 31.
350 /// If you call GetPrivateExponent() then the little-endian byte
351 /// array is converted to a big-endian Integer() so it can be
352 /// returned the way a caller expects. And calling
353 /// SetPrivateExponent perfoms a similar internal conversion.
354 /// \since Crypto++ 8.0
356 {
357  /// \brief Size of the private key
358  /// \details SECRET_KEYLENGTH is the size of the private key, in bytes.
359  CRYPTOPP_CONSTANT(SECRET_KEYLENGTH = 32);
360  /// \brief Size of the public key
361  /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.
362  CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32);
363  /// \brief Size of the siganture
364  /// \details SIGNATURE_LENGTH is the size of the signature, in bytes.
365  /// ed25519 is a DL-based signature scheme. The signature is the
366  /// concatenation of <tt>r || s</tt>.
367  CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64);
368 
369  // CryptoMaterial
370  bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
371  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
372  void AssignFrom(const NameValuePairs &source);
373 
374  // GroupParameters
375  OID GetAlgorithmID() const {
376  return m_oid.Empty() ? ASN1::Ed25519() : m_oid;
377  }
378 
379  /// \brief DER encode ASN.1 object
380  /// \param bt BufferedTransformation object
381  /// \details Save() will write the OID associated with algorithm or scheme.
382  /// In the case of public and private keys, this function writes the
383  /// subjectPubicKeyInfo parts.
384  /// \details The default OID is from RFC 8410 using <tt>id-Ed25519</tt>.
385  /// The default private key format is RFC 5208, which is the old format.
386  /// The old format provides the best interop, and keys will work
387  /// with OpenSSL.
388  /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
389  /// Key Packages</A>
390  void Save(BufferedTransformation &bt) const {
391  DEREncode(bt, 0);
392  }
393 
394  /// \brief DER encode ASN.1 object
395  /// \param bt BufferedTransformation object
396  /// \param v1 flag indicating v1
397  /// \details Save() will write the OID associated with algorithm or scheme.
398  /// In the case of public and private keys, this function writes the
399  /// subjectPubicKeyInfo parts.
400  /// \details The default OID is from RFC 8410 using <tt>id-Ed25519</tt>.
401  /// The default private key format is RFC 5208.
402  /// \details v1 means INTEGER 0 is written. INTEGER 0 means
403  /// RFC 5208 format, which is the old format. The old format provides
404  /// the best interop, and keys will work with OpenSSL. The other
405  /// option uses INTEGER 1. INTEGER 1 means RFC 5958 format,
406  /// which is the new format.
407  /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
408  /// Key Packages</A>
409  void Save(BufferedTransformation &bt, bool v1) const {
410  DEREncode(bt, v1 ? 0 : 1);
411  }
412 
413  /// \brief BER decode ASN.1 object
414  /// \param bt BufferedTransformation object
415  /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
416  /// Key Packages</A>
418  BERDecode(bt);
419  }
420 
421  /// \brief Initializes a public key from this key
422  /// \param pub reference to a public key
423  void MakePublicKey(PublicKey &pub) const;
424 
425  // PKCS8PrivateKey
427  void DEREncode(BufferedTransformation &bt) const { DEREncode(bt, 0); }
428  void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
430 
431  /// \brief DER encode ASN.1 object
432  /// \param bt BufferedTransformation object
433  /// \param version indicates version
434  /// \details DEREncode() will write the OID associated with algorithm or
435  /// scheme. In the case of public and private keys, this function writes
436  /// the subjectPubicKeyInfo parts.
437  /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
438  /// The default private key format is RFC 5208.
439  /// \details The value of version is written as the INTEGER. INTEGER 0 means
440  /// RFC 5208 format, which is the old format. The old format provides
441  /// the best interop, and keys will work with OpenSSL. The INTEGER 1
442  /// means RFC 5958 format, which is the new format.
443  void DEREncode(BufferedTransformation &bt, int version) const;
444 
445  /// \brief Determine if OID is valid for this object
446  /// \details BERDecodeAndCheckAlgorithmID() parses the OID from
447  /// <tt>bt</tt> and determines if it valid for this object. The
448  /// problem in practice is there are multiple OIDs available to
449  /// denote curve25519 operations. The OIDs include an old GNU
450  /// OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves,
451  /// and OIDs specified in draft-ietf-curdle-pkix.
452  /// \details By default BERDecodeAndCheckAlgorithmID() accepts an
453  /// OID set by the user, <tt>ASN1::curve25519()</tt> and <tt>ASN1::Ed25519()</tt>.
454  /// <tt>ASN1::curve25519()</tt> is generic and says "this key is valid for
455  /// curve25519 operations". <tt>ASN1::Ed25519()</tt> is specific and says
456  /// "this key is valid for ed25519 signing."
458 
459  // PKCS8PrivateKey
460  void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params);
461  void SetPrivateExponent(const byte x[SECRET_KEYLENGTH]);
462  void SetPrivateExponent(const Integer &x);
463  const Integer& GetPrivateExponent() const;
464 
465  /// \brief Test if a key has small order
466  /// \param y public key
467  bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const;
468 
469  /// \brief Retrieve private key byte array
470  /// \return the private key byte array
471  /// \details GetPrivateKeyBytePtr() is used by signing code to call ed25519_sign.
472  const byte* GetPrivateKeyBytePtr() const {
473  return m_sk.begin();
474  }
475 
476  /// \brief Retrieve public key byte array
477  /// \return the public key byte array
478  /// \details GetPublicKeyBytePtr() is used by signing code to call ed25519_sign.
479  const byte* GetPublicKeyBytePtr() const {
480  return m_pk.begin();
481  }
482 
483 protected:
484  // Create a public key from a private key
485  void SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const;
486 
487 protected:
490  OID m_oid; // preferred OID
491  mutable Integer m_x; // for DL_PrivateKey
492 };
493 
494 /// \brief Ed25519 signature algorithm
495 /// \since Crypto++ 8.0
496 struct ed25519Signer : public PK_Signer
497 {
498  /// \brief Size of the private key
499  /// \details SECRET_KEYLENGTH is the size of the private key, in bytes.
500  CRYPTOPP_CONSTANT(SECRET_KEYLENGTH = 32);
501  /// \brief Size of the public key
502  /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.
503  CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32);
504  /// \brief Size of the siganture
505  /// \details SIGNATURE_LENGTH is the size of the signature, in bytes.
506  /// ed25519 is a DL-based signature scheme. The signature is the
507  /// concatenation of <tt>r || s</tt>.
508  CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64);
509  typedef Integer Element;
510 
511  virtual ~ed25519Signer() {}
512 
513  /// \brief Create a ed25519Signer object
515 
516  /// \brief Create a ed25519Signer object
517  /// \param y public key
518  /// \param x private key
519  /// \details This constructor creates a ed25519Signer object using existing parameters.
520  /// \note The public key is not validated.
521  ed25519Signer(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]);
522 
523  /// \brief Create a ed25519Signer object
524  /// \param x private key
525  /// \details This constructor creates a ed25519Signer object using existing parameters.
526  /// The public key is calculated from the private key.
527  ed25519Signer(const byte x[SECRET_KEYLENGTH]);
528 
529  /// \brief Create a ed25519Signer object
530  /// \param y public key
531  /// \param x private key
532  /// \details This constructor creates a ed25519Signer object using existing parameters.
533  /// \note The public key is not validated.
534  ed25519Signer(const Integer &y, const Integer &x);
535 
536  /// \brief Create a ed25519Signer object
537  /// \param x private key
538  /// \details This constructor creates a ed25519Signer object using existing parameters.
539  /// The public key is calculated from the private key.
540  ed25519Signer(const Integer &x);
541 
542  /// \brief Create a ed25519Signer object
543  /// \param rng RandomNumberGenerator derived class
544  /// \details This constructor creates a new ed25519Signer using the random number generator.
546 
547  /// \brief Create a ed25519Signer object
548  /// \param params public and private key
549  /// \details This constructor creates a ed25519Signer object using existing parameters.
550  /// The <tt>params</tt> can be created with <tt>Save</tt>.
551  /// \note The public key is not validated.
553 
554  // DL_ObjectImplBase
555  /// \brief Retrieves a reference to a Private Key
556  /// \details AccessKey() retrieves a non-const reference to a private key.
557  PrivateKey& AccessKey() { return m_key; }
558  PrivateKey& AccessPrivateKey() { return m_key; }
559 
560  /// \brief Retrieves a reference to a Private Key
561  /// \details AccessKey() retrieves a const reference to a private key.
562  const PrivateKey& GetKey() const { return m_key; }
563  const PrivateKey& GetPrivateKey() const { return m_key; }
564 
565  // DL_SignatureSchemeBase
566  size_t SignatureLength() const { return SIGNATURE_LENGTH; }
567  size_t MaxRecoverableLength() const { return 0; }
568  size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const {
569  CRYPTOPP_UNUSED(signatureLength); return 0;
570  }
571 
572  bool IsProbabilistic() const { return false; }
573  bool AllowNonrecoverablePart() const { return false; }
574  bool RecoverablePartFirst() const { return false; }
575 
577  return new ed25519_MessageAccumulator(rng);
578  }
579 
580  void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const {
581  CRYPTOPP_UNUSED(messageAccumulator); CRYPTOPP_UNUSED(recoverableMessage);
582  CRYPTOPP_UNUSED(recoverableMessageLength);
583  throw NotImplemented("ed25519Signer: this object does not support recoverable messages");
584  }
585 
586  size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const;
587 
588  /// \brief Sign a stream
589  /// \param rng a RandomNumberGenerator derived class
590  /// \param stream an std::istream derived class
591  /// \param signature a block of bytes for the signature
592  /// \return actual signature length
593  /// \details SignStream() handles large streams. The Stream functions were added to
594  /// ed25519 for signing and verifying files that are too large for a memory allocation.
595  /// The functions are not present in other library signers and verifiers.
596  /// \details ed25519 is a determinsitic signature scheme. <tt>IsProbabilistic()</tt>
597  /// returns false and the random number generator can be <tt>NullRNG()</tt>.
598  /// \pre <tt>COUNTOF(signature) == MaxSignatureLength()</tt>
599  /// \since Crypto++ 8.1
600  size_t SignStream (RandomNumberGenerator &rng, std::istream& stream, byte *signature) const;
601 
602 protected:
603  ed25519PrivateKey m_key;
604 };
605 
606 // ****************** ed25519 Verifier *********************** //
607 
608 /// \brief Ed25519 public key
609 /// \details ed25519PublicKey is somewhat of a hack. It needed to
610 /// provide DL_PublicKey interface to fit into the existing
611 /// framework, but it lacks a lot of the internals of a true
612 /// DL_PublicKey. The missing pieces include GroupParameters
613 /// and Point, which provide the low level field operations
614 /// found in traditional implementations like NIST curves over
615 /// prime and binary fields.
616 /// \details ed25519PublicKey is also unusual because the
617 /// class members of interest are byte arrays and not Integers.
618 /// In addition, the byte arrays are little-endian meaning
619 /// LSB is at element 0 and the MSB is at element 31.
620 /// If you call GetPublicElement() then the little-endian byte
621 /// array is converted to a big-endian Integer() so it can be
622 /// returned the way a caller expects. And calling
623 /// SetPublicElement() perfoms a similar internal conversion.
624 /// \since Crypto++ 8.0
626 {
627  /// \brief Size of the public key
628  /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.
629  CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32);
630  typedef Integer Element;
631 
632  OID GetAlgorithmID() const {
633  return m_oid.Empty() ? ASN1::Ed25519() : m_oid;
634  }
635 
636  /// \brief DER encode ASN.1 object
637  /// \param bt BufferedTransformation object
638  /// \details Save() will write the OID associated with algorithm or scheme.
639  /// In the case of public and private keys, this function writes the
640  /// subjectPubicKeyInfo parts.
641  /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
642  /// The default private key format is RFC 5208, which is the old format.
643  /// The old format provides the best interop, and keys will work
644  /// with OpenSSL.
645  void Save(BufferedTransformation &bt) const {
646  DEREncode(bt);
647  }
648 
649  /// \brief BER decode ASN.1 object
650  /// \param bt BufferedTransformation object
651  /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
652  /// Key Packages</A>
654  BERDecode(bt);
655  }
656 
657  // X509PublicKey
659  void DEREncode(BufferedTransformation &bt) const;
660  void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
661  void DEREncodePublicKey(BufferedTransformation &bt) const;
662 
663  /// \brief Determine if OID is valid for this object
664  /// \details BERDecodeAndCheckAlgorithmID() parses the OID from
665  /// <tt>bt</tt> and determines if it valid for this object. The
666  /// problem in practice is there are multiple OIDs available to
667  /// denote curve25519 operations. The OIDs include an old GNU
668  /// OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves,
669  /// and OIDs specified in draft-ietf-curdle-pkix.
670  /// \details By default BERDecodeAndCheckAlgorithmID() accepts an
671  /// OID set by the user, <tt>ASN1::curve25519()</tt> and <tt>ASN1::Ed25519()</tt>.
672  /// <tt>ASN1::curve25519()</tt> is generic and says "this key is valid for
673  /// curve25519 operations". <tt>ASN1::Ed25519()</tt> is specific and says
674  /// "this key is valid for ed25519 signing."
676 
677  bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
678  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
679  void AssignFrom(const NameValuePairs &source);
680 
681  // DL_PublicKey
682  void SetPublicElement(const byte y[PUBLIC_KEYLENGTH]);
683  void SetPublicElement(const Element &y);
684  const Element& GetPublicElement() const;
685 
686  /// \brief Retrieve public key byte array
687  /// \return the public key byte array
688  /// \details GetPublicKeyBytePtr() is used by signing code to call ed25519_sign.
689  const byte* GetPublicKeyBytePtr() const {
690  return m_pk.begin();
691  }
692 
693 protected:
695  OID m_oid; // preferred OID
696  mutable Integer m_y; // for DL_PublicKey
697 };
698 
699 /// \brief Ed25519 signature verification algorithm
700 /// \since Crypto++ 8.0
702 {
703  CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32);
704  CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64);
705  typedef Integer Element;
706 
707  virtual ~ed25519Verifier() {}
708 
709  /// \brief Create a ed25519Verifier object
711 
712  /// \brief Create a ed25519Verifier object
713  /// \param y public key
714  /// \details This constructor creates a ed25519Verifier object using existing parameters.
715  /// \note The public key is not validated.
716  ed25519Verifier(const byte y[PUBLIC_KEYLENGTH]);
717 
718  /// \brief Create a ed25519Verifier object
719  /// \param y public key
720  /// \details This constructor creates a ed25519Verifier object using existing parameters.
721  /// \note The public key is not validated.
722  ed25519Verifier(const Integer &y);
723 
724  /// \brief Create a ed25519Verifier object
725  /// \param params public and private key
726  /// \details This constructor creates a ed25519Verifier object using existing parameters.
727  /// The <tt>params</tt> can be created with <tt>Save</tt>.
728  /// \note The public key is not validated.
730 
731  /// \brief Create a ed25519Verifier object
732  /// \param signer ed25519 signer object
733  /// \details This constructor creates a ed25519Verifier object using existing parameters.
734  /// The <tt>params</tt> can be created with <tt>Save</tt>.
735  /// \note The public key is not validated.
736  ed25519Verifier(const ed25519Signer& signer);
737 
738  // DL_ObjectImplBase
739  /// \brief Retrieves a reference to a Public Key
740  /// \details AccessKey() retrieves a non-const reference to a public key.
741  PublicKey& AccessKey() { return m_key; }
742  PublicKey& AccessPublicKey() { return m_key; }
743 
744  /// \brief Retrieves a reference to a Public Key
745  /// \details GetKey() retrieves a const reference to a public key.
746  const PublicKey& GetKey() const { return m_key; }
747  const PublicKey& GetPublicKey() const { return m_key; }
748 
749  // DL_SignatureSchemeBase
750  size_t SignatureLength() const { return SIGNATURE_LENGTH; }
751  size_t MaxRecoverableLength() const { return 0; }
752  size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const {
753  CRYPTOPP_UNUSED(signatureLength); return 0;
754  }
755 
756  bool IsProbabilistic() const { return false; }
757  bool AllowNonrecoverablePart() const { return false; }
758  bool RecoverablePartFirst() const { return false; }
759 
761  return new ed25519_MessageAccumulator;
762  }
763 
764  void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const {
765  CRYPTOPP_ASSERT(signature != NULLPTR);
766  CRYPTOPP_ASSERT(signatureLength == SIGNATURE_LENGTH);
767  ed25519_MessageAccumulator& accum = static_cast<ed25519_MessageAccumulator&>(messageAccumulator);
768  if (signature && signatureLength)
769  std::memcpy(accum.signature(), signature, STDMIN((size_t)SIGNATURE_LENGTH, signatureLength));
770  }
771 
772  bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
773 
774  /// \brief Check whether input signature is a valid signature for input message
775  /// \param stream an std::istream derived class
776  /// \param signature a pointer to the signature over the message
777  /// \param signatureLen the size of the signature
778  /// \return true if the signature is valid, false otherwise
779  /// \details VerifyStream() handles large streams. The Stream functions were added to
780  /// ed25519 for signing and verifying files that are too large for a memory allocation.
781  /// The functions are not present in other library signers and verifiers.
782  /// \since Crypto++ 8.1
783  bool VerifyStream(std::istream& stream, const byte *signature, size_t signatureLen) const;
784 
785  DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const {
786  CRYPTOPP_UNUSED(recoveredMessage); CRYPTOPP_UNUSED(messageAccumulator);
787  throw NotImplemented("ed25519Verifier: this object does not support recoverable messages");
788  }
789 
790 protected:
791  ed25519PublicKey m_key;
792 };
793 
794 /// \brief Ed25519 signature scheme
795 /// \sa <A HREF="http://cryptopp.com/wiki/Ed25519">Ed25519</A> on the Crypto++ wiki.
796 /// \since Crypto++ 8.0
797 struct ed25519
798 {
799  /// \brief ed25519 Signer
801  /// \brief ed25519 Verifier
803 };
804 
805 NAMESPACE_END // CryptoPP
806 
807 #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:390
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:238
Ed25519 private key.
Definition: xed25519.h:355
void Save(BufferedTransformation &bt, bool v1) const
DER encode ASN.1 object.
Definition: xed25519.h:409
x25519()
Create a x25519 object.
Definition: xed25519.h:74
void Load(BufferedTransformation &bt)
BER decode ASN.1 object.
Definition: xed25519.h:653
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition: xed25519.cpp:340
bool IsProbabilistic() const
Determines whether a signature scheme requires a random number generator.
Definition: xed25519.h:756
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.h:200
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
Recover a message from its signature.
Definition: xed25519.h:785
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:567
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
Definition: xed25519.h:689
Encodes and Decodes privateKeyInfo.
Definition: asn.h:747
Ed25519 signature verification algorithm.
Definition: xed25519.h:701
PublicKey & AccessKey()
Retrieves a reference to a Public Key.
Definition: xed25519.h:741
Interface for public-key signers.
Definition: cryptlib.h:2855
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:298
bool AllowNonrecoverablePart() const
Determines whether the non-recoverable message part can be signed.
Definition: xed25519.h:573
ASN.1 object identifiers for algorthms and schemes.
bool IsProbabilistic() const
Determines whether a signature scheme requires a random number generator.
Definition: xed25519.h:572
bool AllowNonrecoverablePart() const
Determines whether the non-recoverable message part can be signed.
Definition: xed25519.h:757
void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
Input signature into a message accumulator.
Definition: xed25519.h:764
void Restart()
Reset the accumulator.
Definition: xed25519.h:304
size_t size() const
Retrieve size of data buffer.
Definition: xed25519.h:329
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate a public key from a private key in this domain.
Definition: xed25519.cpp:357
PrivateKey & AccessKey()
Retrieves a reference to a Private Key.
Definition: xed25519.h:557
Interface for random number generators.
Definition: cryptlib.h:1413
ed25519Verifier()
Create a ed25519Verifier object.
Definition: xed25519.h:710
static const int SECRET_KEYLENGTH
Size of the private key.
Definition: xed25519.h:59
ed25519Signer Signer
ed25519 Signer
Definition: xed25519.h:800
Interface for buffered transformations.
Definition: cryptlib.h:1630
Interface for private keys.
Definition: cryptlib.h:2519
OID GetAlgorithmID() const
Retrieves the OID of the algorithm.
Definition: xed25519.h:632
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:568
PublicKey & AccessPublicKey()
Retrieves a reference to a Public Key.
Definition: xed25519.h:742
const PublicKey & GetPublicKey() const
Retrieves a reference to a Public Key.
Definition: xed25519.h:747
bool Empty() const
Determine if OID is empty.
Definition: asn.h:311
Interface for domains of simple key agreement protocols.
Definition: cryptlib.h:2991
const byte * signature() const
Retrieve pointer to signature buffer.
Definition: xed25519.h:317
Returns a decoding results.
Definition: cryptlib.h:277
void ClampKey(byte x[SECRET_KEYLENGTH]) const
Clamp a private key.
Definition: xed25519.cpp:128
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate private key in this domain.
Definition: xed25519.cpp:351
const byte * data() const
Retrieve pointer to data buffer.
Definition: xed25519.h:323
A method was called which was not implemented.
Definition: cryptlib.h:232
void SetAlgorithmID(const OID &oid)
Set the Object Identifier.
Definition: xed25519.h:144
bool RecoverablePartFirst() const
Determines whether the recoverable part must be input before the non-recoverable part.
Definition: xed25519.h:758
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: xed25519.cpp:287
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:237
const PublicKey & GetKey() const
Retrieves a reference to a Public Key.
Definition: xed25519.h:746
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:750
const PrivateKey & GetPrivateKey() const
Retrieves a reference to a Private Key.
Definition: xed25519.h:563
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: xed25519.h:427
void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
Input a recoverable message to an accumulator.
Definition: xed25519.h:580
bool RecoverablePartFirst() const
Determines whether the recoverable part must be input before the non-recoverable part.
Definition: xed25519.h:574
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: xed25519.cpp:163
PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const
Create a new HashTransformation to accumulate the message to be signed.
Definition: xed25519.h:576
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:235
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:635
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68
void Save(BufferedTransformation &bt, bool v1) const
DER encode ASN.1 object.
Definition: xed25519.h:186
ed25519 message accumulator
Definition: xed25519.h:278
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: xed25519.cpp:264
Ed25519 signature algorithm.
Definition: xed25519.h:496
Interface for accumulating messages to be signed or verified.
Definition: cryptlib.h:2839
ed25519_MessageAccumulator(RandomNumberGenerator &rng)
Create a message accumulator.
Definition: xed25519.h:291
ed25519Verifier Verifier
ed25519 Verifier
Definition: xed25519.h:802
bool IsClamped(const byte x[SECRET_KEYLENGTH]) const
Determine if private key is clamped.
Definition: xed25519.cpp:133
const PrivateKey & GetKey() const
Retrieves a reference to a Private Key.
Definition: xed25519.h:562
void Save(BufferedTransformation &bt) const
DER encode ASN.1 object.
Definition: xed25519.h:167
bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
Test if a key has small order.
Definition: xed25519.cpp:138
Interface for public-key signature verifiers.
Definition: cryptlib.h:2919
CryptoParameters & AccessCryptoParameters()
Retrieves a reference to Crypto Parameters.
Definition: xed25519.h:154
OID GetAlgorithmID() const
Get the Object Identifier.
Definition: xed25519.h:138
void Load(BufferedTransformation &bt)
BER decode ASN.1 object.
Definition: xed25519.h:417
size_t MaxRecoverableLength() const
Provides the length of longest message that can be recovered.
Definition: xed25519.h:751
void Save(BufferedTransformation &bt) const
DER encode ASN.1 object.
Definition: xed25519.h:645
PrivateKey & AccessPrivateKey()
Retrieves a reference to a Private Key.
Definition: xed25519.h:558
Interface for crypto prameters.
Definition: cryptlib.h:2524
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:752
Interface for public keys.
Definition: cryptlib.h:2514
Crypto++ library namespace.
Encodes and decodes subjectPublicKeyInfo.
Definition: asn.h:701
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
Derive agreed value.
Definition: xed25519.cpp:363
ed25519Signer()
Create a ed25519Signer object.
Definition: xed25519.h:514
const byte * GetPrivateKeyBytePtr() const
Retrieve private key byte array.
Definition: xed25519.h:472
unsigned int AgreedValueLength() const
Provides the size of the agreed value.
Definition: xed25519.h:236
OID GetAlgorithmID() const
Retrieves the OID of the algorithm.
Definition: xed25519.h:375
Ed25519 public key.
Definition: xed25519.h:625
Ed25519 signature scheme.
Definition: xed25519.h:797
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: xed25519.cpp:316
Object Identifier.
Definition: asn.h:264
ed25519_MessageAccumulator()
Create a message accumulator.
Definition: xed25519.h:284
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
Definition: xed25519.cpp:148
size_t SignatureLength() const
Provides the signature length if it only depends on the key.
Definition: xed25519.h:566
void DEREncodePrivateKey(BufferedTransformation &bt) const
Encode privateKey part of privateKeyInfo.
Definition: xed25519.cpp:256
void Load(BufferedTransformation &bt)
BER decode ASN.1 object.
Definition: xed25519.h:194
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
Definition: xed25519.h:479
ed25519_MessageAccumulator * NewVerificationAccumulator() const
Create a new HashTransformation to accumulate the message to be verified.
Definition: xed25519.h:760
byte * signature()
Retrieve pointer to signature buffer.
Definition: xed25519.h:311
Interface for retrieving values given their names.
Definition: cryptlib.h:321