Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/xed25519.h
Line
Count
Source (jump to first uncovered line)
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
67
28
    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 performing key agreement you should use a
73
    ///   constructor that generates random parameters on construction.
74
28
    x25519() {}
CryptoPP::x25519::x25519()
Line
Count
Source
74
28
    x25519() {}
Unexecuted instantiation: CryptoPP::x25519::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.
138
0
    OID GetAlgorithmID() const {
139
0
        return m_oid.Empty() ? ASN1::X25519() : m_oid;
140
0
    }
141
142
    /// \brief Set the Object Identifier
143
    /// \param oid the new Object Identifier
144
0
    void SetAlgorithmID(const OID& oid) {
145
0
        m_oid = oid;
146
0
    }
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
154
0
    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
    ///  subjectPublicKeyInfo 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
0
    void Save(BufferedTransformation &bt) const {
168
0
        DEREncode(bt, 0);
169
0
    }
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
    ///  subjectPublicKeyInfo 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
0
    void Save(BufferedTransformation &bt, bool v1) const {
187
0
        DEREncode(bt, v1 ? 0 : 1);
188
0
    }
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>
194
0
    void Load(BufferedTransformation &bt) {
195
0
        BERDecode(bt);
196
0
    }
197
198
    // PKCS8PrivateKey
199
    void BERDecode(BufferedTransformation &bt);
200
0
    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 subjectPublicKeyInfo 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
236
0
    unsigned int AgreedValueLength() const {return SHARED_KEYLENGTH;}
237
0
    unsigned int PrivateKeyLength() const {return SECRET_KEYLENGTH;}
238
0
    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
284
0
    ed25519_MessageAccumulator() {
285
0
        Restart();
286
0
    }
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.
291
0
    ed25519_MessageAccumulator(RandomNumberGenerator &rng) {
292
0
        CRYPTOPP_UNUSED(rng); Restart();
293
0
    }
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
0
    void Update(const byte* msg, size_t len) {
299
0
        if (msg && len)
300
0
            m_msg.insert(m_msg.end(), msg, msg+len);
301
0
    }
302
303
    /// \brief Reset the accumulator
304
0
    void Restart() {
305
0
        m_msg.reserve(RESERVE_SIZE);
306
0
        m_msg.resize(SIGNATURE_LENGTH);
307
0
    }
308
309
    /// \brief Retrieve pointer to signature buffer
310
    /// \return pointer to signature buffer
311
0
    byte* signature() {
312
0
        return &m_msg[0];
313
0
    }
314
315
    /// \brief Retrieve pointer to signature buffer
316
    /// \return pointer to signature buffer
317
0
    const byte* signature() const {
318
0
        return &m_msg[0];
319
0
    }
320
321
    /// \brief Retrieve pointer to data buffer
322
    /// \return pointer to data buffer
323
0
    const byte* data() const {
324
0
        return &m_msg[0]+SIGNATURE_LENGTH;
325
0
    }
326
327
    /// \brief Retrieve size of data buffer
328
    /// \return size of the data buffer, in bytes
329
0
    size_t size() const {
330
0
        return m_msg.size()-SIGNATURE_LENGTH;
331
0
    }
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 performs 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 signature
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
0
    virtual ~ed25519PrivateKey() {}
370
371
    // CryptoMaterial
372
    bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
373
    bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
374
    void AssignFrom(const NameValuePairs &source);
375
376
    // GroupParameters
377
0
    OID GetAlgorithmID() const {
378
0
        return m_oid.Empty() ? ASN1::Ed25519() : m_oid;
379
0
    }
380
381
    /// \brief DER encode ASN.1 object
382
    /// \param bt BufferedTransformation object
383
    /// \details Save() will write the OID associated with algorithm or scheme.
384
    ///  In the case of public and private keys, this function writes the
385
    ///  subjectPublicKeyInfo parts.
386
    /// \details The default OID is from RFC 8410 using <tt>id-Ed25519</tt>.
387
    ///  The default private key format is RFC 5208, which is the old format.
388
    ///  The old format provides the best interop, and keys will work
389
    ///  with OpenSSL.
390
    /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
391
    ///  Key Packages</A>
392
0
    void Save(BufferedTransformation &bt) const {
393
0
        DEREncode(bt, 0);
394
0
    }
395
396
    /// \brief DER encode ASN.1 object
397
    /// \param bt BufferedTransformation object
398
    /// \param v1 flag indicating v1
399
    /// \details Save() will write the OID associated with algorithm or scheme.
400
    ///  In the case of public and private keys, this function writes the
401
    ///  subjectPublicKeyInfo parts.
402
    /// \details The default OID is from RFC 8410 using <tt>id-Ed25519</tt>.
403
    ///  The default private key format is RFC 5208.
404
    /// \details v1 means INTEGER 0 is written. INTEGER 0 means
405
    ///  RFC 5208 format, which is the old format. The old format provides
406
    ///  the best interop, and keys will work with OpenSSL. The other
407
    ///  option uses INTEGER 1. INTEGER 1 means RFC 5958 format,
408
    ///  which is the new format.
409
    /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
410
    ///  Key Packages</A>
411
0
    void Save(BufferedTransformation &bt, bool v1) const {
412
0
        DEREncode(bt, v1 ? 0 : 1);
413
0
    }
414
415
    /// \brief BER decode ASN.1 object
416
    /// \param bt BufferedTransformation object
417
    /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
418
    ///  Key Packages</A>
419
0
    void Load(BufferedTransformation &bt) {
420
0
        BERDecode(bt);
421
0
    }
422
423
    /// \brief Initializes a public key from this key
424
    /// \param pub reference to a public key
425
    void MakePublicKey(PublicKey &pub) const;
426
427
    // PKCS8PrivateKey
428
    void BERDecode(BufferedTransformation &bt);
429
0
    void DEREncode(BufferedTransformation &bt) const { DEREncode(bt, 0); }
430
    void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
431
    void DEREncodePrivateKey(BufferedTransformation &bt) const;
432
433
    /// \brief DER encode ASN.1 object
434
    /// \param bt BufferedTransformation object
435
    /// \param version indicates version
436
    /// \details DEREncode() will write the OID associated with algorithm or
437
    ///  scheme. In the case of public and private keys, this function writes
438
    ///  the subjectPublicKeyInfo parts.
439
    /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
440
    ///  The default private key format is RFC 5208.
441
    /// \details The value of version is written as the INTEGER. INTEGER 0 means
442
    ///  RFC 5208 format, which is the old format. The old format provides
443
    ///  the best interop, and keys will work with OpenSSL. The INTEGER 1
444
    ///  means RFC 5958 format, which is the new format.
445
    void DEREncode(BufferedTransformation &bt, int version) const;
446
447
    /// \brief Determine if OID is valid for this object
448
    /// \details BERDecodeAndCheckAlgorithmID() parses the OID from
449
    ///  <tt>bt</tt> and determines if it valid for this object. The
450
    ///  problem in practice is there are multiple OIDs available to
451
    ///  denote curve25519 operations. The OIDs include an old GNU
452
    ///  OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves,
453
    ///  and OIDs specified in draft-ietf-curdle-pkix.
454
    /// \details By default BERDecodeAndCheckAlgorithmID() accepts an
455
    ///  OID set by the user, <tt>ASN1::curve25519()</tt> and <tt>ASN1::Ed25519()</tt>.
456
    ///  <tt>ASN1::curve25519()</tt> is generic and says "this key is valid for
457
    ///  curve25519 operations". <tt>ASN1::Ed25519()</tt> is specific and says
458
    ///  "this key is valid for ed25519 signing."
459
    void BERDecodeAndCheckAlgorithmID(BufferedTransformation& bt);
460
461
    // PKCS8PrivateKey
462
    void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params);
463
    void SetPrivateExponent(const byte x[SECRET_KEYLENGTH]);
464
    void SetPrivateExponent(const Integer &x);
465
    const Integer& GetPrivateExponent() const;
466
467
    /// \brief Test if a key has small order
468
    /// \param y public key
469
    bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const;
470
471
    /// \brief Retrieve private key byte array
472
    /// \return the private key byte array
473
    /// \details GetPrivateKeyBytePtr() is used by signing code to call ed25519_sign.
474
0
    const byte* GetPrivateKeyBytePtr() const {
475
0
        return m_sk.begin();
476
0
    }
477
478
    /// \brief Retrieve public key byte array
479
    /// \return the public key byte array
480
    /// \details GetPublicKeyBytePtr() is used by signing code to call ed25519_sign.
481
0
    const byte* GetPublicKeyBytePtr() const {
482
0
        return m_pk.begin();
483
0
    }
484
485
protected:
486
    // Create a public key from a private key
487
    void SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const;
488
489
protected:
490
    FixedSizeSecBlock<byte, SECRET_KEYLENGTH> m_sk;
491
    FixedSizeSecBlock<byte, PUBLIC_KEYLENGTH> m_pk;
492
    OID m_oid;  // preferred OID
493
    mutable Integer m_x;  // for DL_PrivateKey
494
};
495
496
/// \brief Ed25519 signature algorithm
497
/// \since Crypto++ 8.0
498
struct ed25519Signer : public PK_Signer
499
{
500
    /// \brief Size of the private key
501
    /// \details SECRET_KEYLENGTH is the size of the private key, in bytes.
502
    CRYPTOPP_CONSTANT(SECRET_KEYLENGTH = 32);
503
    /// \brief Size of the public key
504
    /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.
505
    CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32);
506
    /// \brief Size of the signature
507
    /// \details SIGNATURE_LENGTH is the size of the signature, in bytes.
508
    ///  ed25519 is a DL-based signature scheme. The signature is the
509
    ///  concatenation of <tt>r || s</tt>.
510
    CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64);
511
    typedef Integer Element;
512
513
0
    virtual ~ed25519Signer() {}
514
515
    /// \brief Create an ed25519Signer object
516
0
    ed25519Signer() {}
517
518
    /// \brief Create an ed25519Signer object
519
    /// \param y public key
520
    /// \param x private key
521
    /// \details This constructor creates an ed25519Signer object using existing parameters.
522
    /// \note The public key is not validated.
523
    ed25519Signer(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]);
524
525
    /// \brief Create an ed25519Signer object
526
    /// \param x private key
527
    /// \details This constructor creates an ed25519Signer object using existing parameters.
528
    ///  The public key is calculated from the private key.
529
    ed25519Signer(const byte x[SECRET_KEYLENGTH]);
530
531
    /// \brief Create an ed25519Signer object
532
    /// \param y public key
533
    /// \param x private key
534
    /// \details This constructor creates an ed25519Signer object using existing parameters.
535
    /// \note The public key is not validated.
536
    ed25519Signer(const Integer &y, const Integer &x);
537
538
    /// \brief Create an ed25519Signer object
539
    /// \param x private key
540
    /// \details This constructor creates an ed25519Signer object using existing parameters.
541
    ///  The public key is calculated from the private key.
542
    ed25519Signer(const Integer &x);
543
544
    /// \brief Create an ed25519Signer object
545
    /// \param key PKCS8 private key
546
    /// \details This constructor creates an ed25519Signer object using existing private key.
547
    /// \note The keys are not validated.
548
    /// \since Crypto++ 8.6
549
    ed25519Signer(const PKCS8PrivateKey &key);
550
551
    /// \brief Create an ed25519Signer object
552
    /// \param rng RandomNumberGenerator derived class
553
    /// \details This constructor creates a new ed25519Signer using the random number generator.
554
    ed25519Signer(RandomNumberGenerator &rng);
555
556
    /// \brief Create an ed25519Signer object
557
    /// \param params public and private key
558
    /// \details This constructor creates an ed25519Signer object using existing parameters.
559
    ///  The <tt>params</tt> can be created with <tt>Save</tt>.
560
    /// \note The public key is not validated.
561
    ed25519Signer(BufferedTransformation &params);
562
563
    // DL_ObjectImplBase
564
    /// \brief Retrieves a reference to a Private Key
565
    /// \details AccessKey() retrieves a non-const reference to a private key.
566
0
    PrivateKey& AccessKey() { return m_key; }
567
0
    PrivateKey& AccessPrivateKey() { return m_key; }
568
569
    /// \brief Retrieves a reference to a Private Key
570
    /// \details AccessKey() retrieves a const reference to a private key.
571
0
    const PrivateKey& GetKey() const { return m_key; }
572
0
    const PrivateKey& GetPrivateKey() const { return m_key; }
573
574
    // DL_SignatureSchemeBase
575
0
    size_t SignatureLength() const { return SIGNATURE_LENGTH; }
576
0
    size_t MaxRecoverableLength() const { return 0; }
577
0
    size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const {
578
0
        CRYPTOPP_UNUSED(signatureLength); return 0;
579
0
    }
580
581
0
    bool IsProbabilistic() const { return false; }
582
0
    bool AllowNonrecoverablePart() const { return false; }
583
0
    bool RecoverablePartFirst() const { return false; }
584
585
0
    PK_MessageAccumulator* NewSignatureAccumulator(RandomNumberGenerator &rng) const {
586
0
        return new ed25519_MessageAccumulator(rng);
587
0
    }
588
589
0
    void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const {
590
0
        CRYPTOPP_UNUSED(messageAccumulator); CRYPTOPP_UNUSED(recoverableMessage);
591
0
        CRYPTOPP_UNUSED(recoverableMessageLength);
592
0
        throw NotImplemented("ed25519Signer: this object does not support recoverable messages");
593
0
    }
594
595
    size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const;
596
597
    /// \brief Sign a stream
598
    /// \param rng a RandomNumberGenerator derived class
599
    /// \param stream an std::istream derived class
600
    /// \param signature a block of bytes for the signature
601
    /// \return actual signature length
602
    /// \details SignStream() handles large streams. The Stream functions were added to
603
    ///  ed25519 for signing and verifying files that are too large for a memory allocation.
604
    ///  The functions are not present in other library signers and verifiers.
605
    /// \details ed25519 is a deterministic signature scheme. <tt>IsProbabilistic()</tt>
606
    ///  returns false and the random number generator can be <tt>NullRNG()</tt>.
607
    /// \pre <tt>COUNTOF(signature) == MaxSignatureLength()</tt>
608
    /// \since Crypto++ 8.1
609
    size_t SignStream (RandomNumberGenerator &rng, std::istream& stream, byte *signature) const;
610
611
protected:
612
    ed25519PrivateKey m_key;
613
};
614
615
// ****************** ed25519 Verifier *********************** //
616
617
/// \brief Ed25519 public key
618
/// \details ed25519PublicKey is somewhat of a hack. It needed to
619
///  provide DL_PublicKey interface to fit into the existing
620
///  framework, but it lacks a lot of the internals of a true
621
///  DL_PublicKey. The missing pieces include GroupParameters
622
///  and Point, which provide the low level field operations
623
///  found in traditional implementations like NIST curves over
624
///  prime and binary fields.
625
/// \details ed25519PublicKey is also unusual because the
626
///  class members of interest are byte arrays and not Integers.
627
///  In addition, the byte arrays are little-endian meaning
628
///  LSB is at element 0 and the MSB is at element 31.
629
///  If you call GetPublicElement() then the little-endian byte
630
///  array is converted to a big-endian Integer() so it can be
631
///  returned the way a caller expects. And calling
632
///  SetPublicElement() performs a similar internal conversion.
633
/// \since Crypto++ 8.0
634
struct ed25519PublicKey : public X509PublicKey
635
{
636
    /// \brief Size of the public key
637
    /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.
638
    CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32);
639
    typedef Integer Element;
640
641
0
    virtual ~ed25519PublicKey() {}
642
643
0
    OID GetAlgorithmID() const {
644
0
        return m_oid.Empty() ? ASN1::Ed25519() : m_oid;
645
0
    }
646
647
    /// \brief DER encode ASN.1 object
648
    /// \param bt BufferedTransformation object
649
    /// \details Save() will write the OID associated with algorithm or scheme.
650
    ///  In the case of public and private keys, this function writes the
651
    ///  subjectPublicKeyInfo parts.
652
    /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.
653
    ///  The default private key format is RFC 5208, which is the old format.
654
    ///  The old format provides the best interop, and keys will work
655
    ///  with OpenSSL.
656
0
    void Save(BufferedTransformation &bt) const {
657
0
        DEREncode(bt);
658
0
    }
659
660
    /// \brief BER decode ASN.1 object
661
    /// \param bt BufferedTransformation object
662
    /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric
663
    ///  Key Packages</A>
664
0
    void Load(BufferedTransformation &bt) {
665
0
        BERDecode(bt);
666
0
    }
667
668
    // X509PublicKey
669
    void BERDecode(BufferedTransformation &bt);
670
    void DEREncode(BufferedTransformation &bt) const;
671
    void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
672
    void DEREncodePublicKey(BufferedTransformation &bt) const;
673
674
    /// \brief Determine if OID is valid for this object
675
    /// \details BERDecodeAndCheckAlgorithmID() parses the OID from
676
    ///  <tt>bt</tt> and determines if it valid for this object. The
677
    ///  problem in practice is there are multiple OIDs available to
678
    ///  denote curve25519 operations. The OIDs include an old GNU
679
    ///  OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves,
680
    ///  and OIDs specified in draft-ietf-curdle-pkix.
681
    /// \details By default BERDecodeAndCheckAlgorithmID() accepts an
682
    ///  OID set by the user, <tt>ASN1::curve25519()</tt> and <tt>ASN1::Ed25519()</tt>.
683
    ///  <tt>ASN1::curve25519()</tt> is generic and says "this key is valid for
684
    ///  curve25519 operations". <tt>ASN1::Ed25519()</tt> is specific and says
685
    ///  "this key is valid for ed25519 signing."
686
    void BERDecodeAndCheckAlgorithmID(BufferedTransformation& bt);
687
688
    bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
689
    bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
690
    void AssignFrom(const NameValuePairs &source);
691
692
    // DL_PublicKey
693
    void SetPublicElement(const byte y[PUBLIC_KEYLENGTH]);
694
    void SetPublicElement(const Element &y);
695
    const Element& GetPublicElement() const;
696
697
    /// \brief Retrieve public key byte array
698
    /// \return the public key byte array
699
    /// \details GetPublicKeyBytePtr() is used by signing code to call ed25519_sign.
700
0
    const byte* GetPublicKeyBytePtr() const {
701
0
        return m_pk.begin();
702
0
    }
703
704
protected:
705
    FixedSizeSecBlock<byte, PUBLIC_KEYLENGTH> m_pk;
706
    OID m_oid;  // preferred OID
707
    mutable Integer m_y;  // for DL_PublicKey
708
};
709
710
/// \brief Ed25519 signature verification algorithm
711
/// \since Crypto++ 8.0
712
struct ed25519Verifier : public PK_Verifier
713
{
714
    CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32);
715
    CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64);
716
    typedef Integer Element;
717
718
0
    virtual ~ed25519Verifier() {}
719
720
    /// \brief Create an ed25519Verifier object
721
0
    ed25519Verifier() {}
722
723
    /// \brief Create an ed25519Verifier object
724
    /// \param y public key
725
    /// \details This constructor creates an ed25519Verifier object using existing parameters.
726
    /// \note The public key is not validated.
727
    ed25519Verifier(const byte y[PUBLIC_KEYLENGTH]);
728
729
    /// \brief Create an ed25519Verifier object
730
    /// \param y public key
731
    /// \details This constructor creates an ed25519Verifier object using existing parameters.
732
    /// \note The public key is not validated.
733
    ed25519Verifier(const Integer &y);
734
735
    /// \brief Create an ed25519Verifier object
736
    /// \param key X509 public key
737
    /// \details This constructor creates an ed25519Verifier object using an existing public key.
738
    /// \note The public key is not validated.
739
    /// \since Crypto++ 8.6
740
    ed25519Verifier(const X509PublicKey &key);
741
742
    /// \brief Create an ed25519Verifier object
743
    /// \param params public and private key
744
    /// \details This constructor creates an ed25519Verifier object using existing parameters.
745
    ///  The <tt>params</tt> can be created with <tt>Save</tt>.
746
    /// \note The public key is not validated.
747
    ed25519Verifier(BufferedTransformation &params);
748
749
    /// \brief Create an ed25519Verifier object
750
    /// \param signer ed25519 signer object
751
    /// \details This constructor creates an ed25519Verifier object using existing parameters.
752
    ///  The <tt>params</tt> can be created with <tt>Save</tt>.
753
    /// \note The public key is not validated.
754
    ed25519Verifier(const ed25519Signer& signer);
755
756
    // DL_ObjectImplBase
757
    /// \brief Retrieves a reference to a Public Key
758
    /// \details AccessKey() retrieves a non-const reference to a public key.
759
0
    PublicKey& AccessKey() { return m_key; }
760
0
    PublicKey& AccessPublicKey() { return m_key; }
761
762
    /// \brief Retrieves a reference to a Public Key
763
    /// \details GetKey() retrieves a const reference to a public key.
764
0
    const PublicKey& GetKey() const { return m_key; }
765
0
    const PublicKey& GetPublicKey() const { return m_key; }
766
767
    // DL_SignatureSchemeBase
768
0
    size_t SignatureLength() const { return SIGNATURE_LENGTH; }
769
0
    size_t MaxRecoverableLength() const { return 0; }
770
0
    size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const {
771
0
        CRYPTOPP_UNUSED(signatureLength); return 0;
772
0
    }
773
774
0
    bool IsProbabilistic() const { return false; }
775
0
    bool AllowNonrecoverablePart() const { return false; }
776
0
    bool RecoverablePartFirst() const { return false; }
777
778
0
    ed25519_MessageAccumulator* NewVerificationAccumulator() const {
779
0
        return new ed25519_MessageAccumulator;
780
0
    }
781
782
0
    void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const {
783
0
        CRYPTOPP_ASSERT(signature != NULLPTR);
784
0
        CRYPTOPP_ASSERT(signatureLength == SIGNATURE_LENGTH);
785
0
        ed25519_MessageAccumulator& accum = static_cast<ed25519_MessageAccumulator&>(messageAccumulator);
786
0
        if (signature && signatureLength)
787
0
            std::memcpy(accum.signature(), signature, STDMIN((size_t)SIGNATURE_LENGTH, signatureLength));
788
0
    }
789
790
    bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
791
792
    /// \brief Check whether input signature is a valid signature for input message
793
    /// \param stream an std::istream derived class
794
    /// \param signature a pointer to the signature over the message
795
    /// \param signatureLen the size of the signature
796
    /// \return true if the signature is valid, false otherwise
797
    /// \details VerifyStream() handles large streams. The Stream functions were added to
798
    ///  ed25519 for signing and verifying files that are too large for a memory allocation.
799
    ///  The functions are not present in other library signers and verifiers.
800
    /// \since Crypto++ 8.1
801
    bool VerifyStream(std::istream& stream, const byte *signature, size_t signatureLen) const;
802
803
0
    DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const {
804
0
        CRYPTOPP_UNUSED(recoveredMessage); CRYPTOPP_UNUSED(messageAccumulator);
805
0
        throw NotImplemented("ed25519Verifier: this object does not support recoverable messages");
806
0
    }
807
808
protected:
809
    ed25519PublicKey m_key;
810
};
811
812
/// \brief Ed25519 signature scheme
813
/// \sa <A HREF="http://cryptopp.com/wiki/Ed25519">Ed25519</A> on the Crypto++ wiki.
814
/// \since Crypto++ 8.0
815
struct ed25519
816
{
817
    /// \brief ed25519 Signer
818
    typedef ed25519Signer Signer;
819
    /// \brief ed25519 Verifier
820
    typedef ed25519Verifier Verifier;
821
};
822
823
NAMESPACE_END  // CryptoPP
824
825
#endif  // CRYPTOPP_XED25519_H