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
54 class x25519 : public SimpleKeyAgreementDomain, public CryptoParameters, public PKCS8PrivateKey
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 
~x25519()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.
x25519()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.
105     x25519(RandomNumberGenerator &rng);
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.
112     x25519(BufferedTransformation &params);
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.
GetAlgorithmID()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
SetAlgorithmID(const OID & oid)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
AccessCryptoParameters()154     CryptoParameters & AccessCryptoParameters() {return *this;}
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>
Save(BufferedTransformation & bt)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>
Save(BufferedTransformation & bt,bool v1)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>
Load(BufferedTransformation & bt)194     void Load(BufferedTransformation &bt) {
195         BERDecode(bt);
196     }
197 
198     // PKCS8PrivateKey
199     void BERDecode(BufferedTransformation &bt);
DEREncode(BufferedTransformation & bt)200     void DEREncode(BufferedTransformation &bt) const { DEREncode(bt, 0); }
201     void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
202     void DEREncodePrivateKey(BufferedTransformation &bt) const;
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."
230     void BERDecodeAndCheckAlgorithmID(BufferedTransformation& bt);
231 
232     // DL_PrivateKey
233     void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params);
234 
235     // SimpleKeyAgreementDomain
AgreedValueLength()236     unsigned int AgreedValueLength() const {return SHARED_KEYLENGTH;}
PrivateKeyLength()237     unsigned int PrivateKeyLength() const {return SECRET_KEYLENGTH;}
PublicKeyLength()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:
250     FixedSizeSecBlock<byte, SECRET_KEYLENGTH> m_sk;
251     FixedSizeSecBlock<byte, PUBLIC_KEYLENGTH> m_pk;
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.
278 struct ed25519_MessageAccumulator : public PK_MessageAccumulator
279 {
280     CRYPTOPP_CONSTANT(RESERVE_SIZE=2048+64);
281     CRYPTOPP_CONSTANT(SIGNATURE_LENGTH=64);
282 
283     /// \brief Create a message accumulator
ed25519_MessageAccumulatored25519_MessageAccumulator284     ed25519_MessageAccumulator() {
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.
ed25519_MessageAccumulatored25519_MessageAccumulator291     ed25519_MessageAccumulator(RandomNumberGenerator &rng) {
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
Updateed25519_MessageAccumulator298     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
Restarted25519_MessageAccumulator304     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
signatureed25519_MessageAccumulator311     byte* signature() {
312         return &m_msg[0];
313     }
314 
315     /// \brief Retrieve pointer to signature buffer
316     /// \return pointer to signature buffer
signatureed25519_MessageAccumulator317     const byte* signature() const {
318         return &m_msg[0];
319     }
320 
321     /// \brief Retrieve pointer to data buffer
322     /// \return pointer to data buffer
dataed25519_MessageAccumulator323     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
sizeed25519_MessageAccumulator329     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
355 struct ed25519PrivateKey : public PKCS8PrivateKey
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
GetAlgorithmIDed25519PrivateKey375     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>
Saveed25519PrivateKey390     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>
Saveed25519PrivateKey409     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>
Loaded25519PrivateKey417     void Load(BufferedTransformation &bt) {
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
426     void BERDecode(BufferedTransformation &bt);
DEREncodeed25519PrivateKey427     void DEREncode(BufferedTransformation &bt) const { DEREncode(bt, 0); }
428     void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
429     void DEREncodePrivateKey(BufferedTransformation &bt) const;
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."
457     void BERDecodeAndCheckAlgorithmID(BufferedTransformation& bt);
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.
GetPrivateKeyBytePtred25519PrivateKey472     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.
GetPublicKeyBytePtred25519PrivateKey479     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:
488     FixedSizeSecBlock<byte, SECRET_KEYLENGTH> m_sk;
489     FixedSizeSecBlock<byte, PUBLIC_KEYLENGTH> m_pk;
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 
~ed25519Signered25519Signer511     virtual ~ed25519Signer() {}
512 
513     /// \brief Create a ed25519Signer object
ed25519Signered25519Signer514     ed25519Signer() {}
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.
545     ed25519Signer(RandomNumberGenerator &rng);
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.
552     ed25519Signer(BufferedTransformation &params);
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.
AccessKeyed25519Signer557     PrivateKey& AccessKey() { return m_key; }
AccessPrivateKeyed25519Signer558     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.
GetKeyed25519Signer562     const PrivateKey& GetKey() const { return m_key; }
GetPrivateKeyed25519Signer563     const PrivateKey& GetPrivateKey() const { return m_key; }
564 
565     // DL_SignatureSchemeBase
SignatureLengthed25519Signer566     size_t SignatureLength() const { return SIGNATURE_LENGTH; }
MaxRecoverableLengthed25519Signer567     size_t MaxRecoverableLength() const { return 0; }
MaxRecoverableLengthFromSignatureLengthed25519Signer568     size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const {
569         CRYPTOPP_UNUSED(signatureLength); return 0;
570     }
571 
IsProbabilisticed25519Signer572     bool IsProbabilistic() const { return false; }
AllowNonrecoverableParted25519Signer573     bool AllowNonrecoverablePart() const { return false; }
RecoverablePartFirsted25519Signer574     bool RecoverablePartFirst() const { return false; }
575 
NewSignatureAccumulatored25519Signer576     PK_MessageAccumulator* NewSignatureAccumulator(RandomNumberGenerator &rng) const {
577         return new ed25519_MessageAccumulator(rng);
578     }
579 
InputRecoverableMessageed25519Signer580     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 deterministic 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
625 struct ed25519PublicKey : public X509PublicKey
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 
GetAlgorithmIDed25519PublicKey632     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.
Saveed25519PublicKey645     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>
Loaded25519PublicKey653     void Load(BufferedTransformation &bt) {
654         BERDecode(bt);
655     }
656 
657     // X509PublicKey
658     void BERDecode(BufferedTransformation &bt);
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."
675     void BERDecodeAndCheckAlgorithmID(BufferedTransformation& bt);
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.
GetPublicKeyBytePtred25519PublicKey689     const byte* GetPublicKeyBytePtr() const {
690         return m_pk.begin();
691     }
692 
693 protected:
694     FixedSizeSecBlock<byte, PUBLIC_KEYLENGTH> m_pk;
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
701 struct ed25519Verifier : public PK_Verifier
702 {
703     CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32);
704     CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64);
705     typedef Integer Element;
706 
~ed25519Verifiered25519Verifier707     virtual ~ed25519Verifier() {}
708 
709     /// \brief Create a ed25519Verifier object
ed25519Verifiered25519Verifier710     ed25519Verifier() {}
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.
729     ed25519Verifier(BufferedTransformation &params);
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.
AccessKeyed25519Verifier741     PublicKey& AccessKey() { return m_key; }
AccessPublicKeyed25519Verifier742     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.
GetKeyed25519Verifier746     const PublicKey& GetKey() const { return m_key; }
GetPublicKeyed25519Verifier747     const PublicKey& GetPublicKey() const { return m_key; }
748 
749     // DL_SignatureSchemeBase
SignatureLengthed25519Verifier750     size_t SignatureLength() const { return SIGNATURE_LENGTH; }
MaxRecoverableLengthed25519Verifier751     size_t MaxRecoverableLength() const { return 0; }
MaxRecoverableLengthFromSignatureLengthed25519Verifier752     size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const {
753         CRYPTOPP_UNUSED(signatureLength); return 0;
754     }
755 
IsProbabilisticed25519Verifier756     bool IsProbabilistic() const { return false; }
AllowNonrecoverableParted25519Verifier757     bool AllowNonrecoverablePart() const { return false; }
RecoverablePartFirsted25519Verifier758     bool RecoverablePartFirst() const { return false; }
759 
NewVerificationAccumulatored25519Verifier760     ed25519_MessageAccumulator* NewVerificationAccumulator() const {
761         return new ed25519_MessageAccumulator;
762     }
763 
InputSignatureed25519Verifier764     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 
RecoverAndRestarted25519Verifier785     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
800     typedef ed25519Signer Signer;
801     /// \brief ed25519 Verifier
802     typedef ed25519Verifier Verifier;
803 };
804 
805 NAMESPACE_END  // CryptoPP
806 
807 #endif  // CRYPTOPP_XED25519_H
808