Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:10

0001 // xed25519.h - written and placed in public domain by Jeffrey Walton

0002 //              Crypto++ specific implementation wrapped around Andrew

0003 //              Moon's public domain curve25519-donna and ed25519-donna,

0004 //              http://github.com/floodyberry/curve25519-donna and

0005 //              http://github.com/floodyberry/ed25519-donna.

0006 
0007 // Typically the key agreement classes encapsulate their data more

0008 // than x25519 does below. They are a little more accessible

0009 // due to crypto_box operations.

0010 
0011 /// \file xed25519.h

0012 /// \brief Classes for x25519 and ed25519 operations

0013 /// \details This implementation integrates Andrew Moon's public domain code

0014 ///  for curve25519-donna and ed25519-donna.

0015 /// \details Moving keys into and out of the library proceeds as follows.

0016 ///  If an Integer class is accepted or returned, then the data is in big

0017 ///  endian format. That is, the MSB is at byte position 0, and the LSB

0018 ///  is at byte position 31. The Integer will work as expected, just like

0019 ///  an int or a long.

0020 /// \details If a byte array is accepted, then the byte array is in little

0021 ///  endian format. That is, the LSB is at byte position 0, and the MSB is

0022 ///  at byte position 31. This follows the implementation where byte 0 is

0023 ///  clamed with 248. That is my_arr[0] &= 248 to mask the lower 3 bits.

0024 /// \details PKCS8 and X509 keys encoded using ASN.1 follow little endian

0025 ///  arrays. The format is specified in <A HREF=

0026 ///  "http:///tools.ietf.org/html/draft-ietf-curdle-pkix">draft-ietf-curdle-pkix</A>.

0027 /// \details If you have a little endian array and you want to wrap it in

0028 ///  an Integer using big endian then you can perform the following:

0029 /// <pre>Integer x(my_arr, SECRET_KEYLENGTH, UNSIGNED, LITTLE_ENDIAN_ORDER);</pre>

0030 /// \sa Andrew Moon's x22519 GitHub <A

0031 ///  HREF="http://github.com/floodyberry/curve25519-donna">curve25519-donna</A>,

0032 ///  ed22519 GitHub <A

0033 ///  HREF="http://github.com/floodyberry/ed25519-donna">ed25519-donna</A>, and

0034 ///  <A HREF="http:///tools.ietf.org/html/draft-ietf-curdle-pkix">draft-ietf-curdle-pkix</A>

0035 /// \since Crypto++ 8.0

0036 
0037 #ifndef CRYPTOPP_XED25519_H
0038 #define CRYPTOPP_XED25519_H
0039 
0040 #include "cryptlib.h"
0041 #include "pubkey.h"
0042 #include "oids.h"
0043 
0044 NAMESPACE_BEGIN(CryptoPP)
0045 
0046 class Integer;
0047 struct ed25519Signer;
0048 struct ed25519Verifier;
0049 
0050 // ******************** x25519 Agreement ************************* //

0051 
0052 /// \brief x25519 with key validation

0053 /// \since Crypto++ 8.0

0054 class x25519 : public SimpleKeyAgreementDomain, public CryptoParameters, public PKCS8PrivateKey
0055 {
0056 public:
0057     /// \brief Size of the private key

0058     /// \details SECRET_KEYLENGTH is the size of the private key, in bytes.

0059     CRYPTOPP_CONSTANT(SECRET_KEYLENGTH = 32);
0060     /// \brief Size of the public key

0061     /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.

0062     CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32);
0063     /// \brief Size of the shared key

0064     /// \details SHARED_KEYLENGTH is the size of the shared key, in bytes.

0065     CRYPTOPP_CONSTANT(SHARED_KEYLENGTH = 32);
0066 
0067     virtual ~x25519() {}
0068 
0069     /// \brief Create a x25519 object

0070     /// \details This constructor creates an empty x25519 object. It is

0071     ///  intended for use in loading existing parameters, like CryptoBox

0072     ///  parameters. If you are performing key agreement you should use a

0073     ///   constructor that generates random parameters on construction.

0074     x25519() {}
0075 
0076     /// \brief Create a x25519 object

0077     /// \param y public key

0078     /// \param x private key

0079     /// \details This constructor creates a x25519 object using existing parameters.

0080     /// \note The public key is not validated.

0081     x25519(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]);
0082 
0083     /// \brief Create a x25519 object

0084     /// \param x private key

0085     /// \details This constructor creates a x25519 object using existing parameters.

0086     ///  The public key is calculated from the private key.

0087     x25519(const byte x[SECRET_KEYLENGTH]);
0088 
0089     /// \brief Create a x25519 object

0090     /// \param y public key

0091     /// \param x private key

0092     /// \details This constructor creates a x25519 object using existing parameters.

0093     /// \note The public key is not validated.

0094     x25519(const Integer &y, const Integer &x);
0095 
0096     /// \brief Create a x25519 object

0097     /// \param x private key

0098     /// \details This constructor creates a x25519 object using existing parameters.

0099     ///  The public key is calculated from the private key.

0100     x25519(const Integer &x);
0101 
0102     /// \brief Create a x25519 object

0103     /// \param rng RandomNumberGenerator derived class

0104     /// \details This constructor creates a new x25519 using the random number generator.

0105     x25519(RandomNumberGenerator &rng);
0106 
0107     /// \brief Create a x25519 object

0108     /// \param params public and private key

0109     /// \details This constructor creates a x25519 object using existing parameters.

0110     ///  The <tt>params</tt> can be created with <tt>Save</tt>.

0111     /// \note The public key is not validated.

0112     x25519(BufferedTransformation &params);
0113 
0114     /// \brief Create a x25519 object

0115     /// \param oid an object identifier

0116     /// \details This constructor creates a new x25519 using the specified OID. The public

0117     ///  and private points are uninitialized.

0118     x25519(const OID &oid);
0119 
0120     /// \brief Clamp a private key

0121     /// \param x private key

0122     /// \details ClampKeys() clamps a private key and then regenerates the

0123     ///  public key from the private key.

0124     void ClampKey(byte x[SECRET_KEYLENGTH]) const;
0125 
0126     /// \brief Determine if private key is clamped

0127     /// \param x private key

0128     bool IsClamped(const byte x[SECRET_KEYLENGTH]) const;
0129 
0130     /// \brief Test if a key has small order

0131     /// \param y public key

0132     bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const;
0133 
0134     /// \brief Get the Object Identifier

0135     /// \return the Object Identifier

0136     /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.

0137     ///  The default private key format is RFC 5208.

0138     OID GetAlgorithmID() const {
0139         return m_oid.Empty() ? ASN1::X25519() : m_oid;
0140     }
0141 
0142     /// \brief Set the Object Identifier

0143     /// \param oid the new Object Identifier

0144     void SetAlgorithmID(const OID& oid) {
0145         m_oid = oid;
0146     }
0147 
0148     // CryptoParameters

0149     bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
0150     bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
0151     void AssignFrom(const NameValuePairs &source);
0152 
0153     // CryptoParameters

0154     CryptoParameters & AccessCryptoParameters() {return *this;}
0155 
0156     /// \brief DER encode ASN.1 object

0157     /// \param bt BufferedTransformation object

0158     /// \details Save() will write the OID associated with algorithm or scheme.

0159     ///  In the case of public and private keys, this function writes the

0160     ///  subjectPublicKeyInfo parts.

0161     /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.

0162     ///  The default private key format is RFC 5208, which is the old format.

0163     ///  The old format provides the best interop, and keys will work

0164     ///  with OpenSSL.

0165     /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric

0166     ///  Key Packages</A>

0167     void Save(BufferedTransformation &bt) const {
0168         DEREncode(bt, 0);
0169     }
0170 
0171     /// \brief DER encode ASN.1 object

0172     /// \param bt BufferedTransformation object

0173     /// \param v1 flag indicating v1

0174     /// \details Save() will write the OID associated with algorithm or scheme.

0175     ///  In the case of public and private keys, this function writes the

0176     ///  subjectPublicKeyInfo parts.

0177     /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.

0178     ///  The default private key format is RFC 5208.

0179     /// \details v1 means INTEGER 0 is written. INTEGER 0 means

0180     ///  RFC 5208 format, which is the old format. The old format provides

0181     ///  the best interop, and keys will work with OpenSSL. The other

0182     ///  option uses INTEGER 1. INTEGER 1 means RFC 5958 format,

0183     ///  which is the new format.

0184     /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric

0185     ///  Key Packages</A>

0186     void Save(BufferedTransformation &bt, bool v1) const {
0187         DEREncode(bt, v1 ? 0 : 1);
0188     }
0189 
0190     /// \brief BER decode ASN.1 object

0191     /// \param bt BufferedTransformation object

0192     /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric

0193     ///  Key Packages</A>

0194     void Load(BufferedTransformation &bt) {
0195         BERDecode(bt);
0196     }
0197 
0198     // PKCS8PrivateKey

0199     void BERDecode(BufferedTransformation &bt);
0200     void DEREncode(BufferedTransformation &bt) const { DEREncode(bt, 0); }
0201     void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
0202     void DEREncodePrivateKey(BufferedTransformation &bt) const;
0203 
0204     /// \brief DER encode ASN.1 object

0205     /// \param bt BufferedTransformation object

0206     /// \param version indicates version

0207     /// \details DEREncode() will write the OID associated with algorithm or

0208     ///  scheme. In the case of public and private keys, this function writes

0209     ///  the subjectPublicKeyInfo parts.

0210     /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.

0211     ///  The default private key format is RFC 5208.

0212     /// \details The value of version is written as the INTEGER. INTEGER 0 means

0213     ///  RFC 5208 format, which is the old format. The old format provides

0214     ///  the best interop, and keys will work with OpenSSL. The INTEGER 1

0215     ///  means RFC 5958 format, which is the new format.

0216     void DEREncode(BufferedTransformation &bt, int version) const;
0217 
0218     /// \brief Determine if OID is valid for this object

0219     /// \details BERDecodeAndCheckAlgorithmID() parses the OID from

0220     ///  <tt>bt</tt> and determines if it valid for this object. The

0221     ///  problem in practice is there are multiple OIDs available to

0222     ///  denote curve25519 operations. The OIDs include an old GNU

0223     ///  OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves,

0224     ///  and OIDs specified in draft-ietf-curdle-pkix.

0225     /// \details By default BERDecodeAndCheckAlgorithmID() accepts an

0226     ///  OID set by the user, <tt>ASN1::curve25519()</tt> and <tt>ASN1::X25519()</tt>.

0227     ///  <tt>ASN1::curve25519()</tt> is generic and says "this key is valid for

0228     ///  curve25519 operations". <tt>ASN1::X25519()</tt> is specific and says

0229     ///  "this key is valid for x25519 key exchange."

0230     void BERDecodeAndCheckAlgorithmID(BufferedTransformation& bt);
0231 
0232     // DL_PrivateKey

0233     void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params);
0234 
0235     // SimpleKeyAgreementDomain

0236     unsigned int AgreedValueLength() const {return SHARED_KEYLENGTH;}
0237     unsigned int PrivateKeyLength() const {return SECRET_KEYLENGTH;}
0238     unsigned int PublicKeyLength() const {return PUBLIC_KEYLENGTH;}
0239 
0240     // SimpleKeyAgreementDomain

0241     void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const;
0242     void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const;
0243     bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const;
0244 
0245 protected:
0246     // Create a public key from a private key

0247     void SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const;
0248 
0249 protected:
0250     FixedSizeSecBlock<byte, SECRET_KEYLENGTH> m_sk;
0251     FixedSizeSecBlock<byte, PUBLIC_KEYLENGTH> m_pk;
0252     OID m_oid;  // preferred OID

0253 };
0254 
0255 // ****************** ed25519 Signer *********************** //

0256 
0257 /// \brief ed25519 message accumulator

0258 /// \details ed25519 buffers the entire message, and does not

0259 ///  digest the message incrementally. You should be careful with

0260 ///  large messages like files on-disk. The behavior is by design

0261 ///  because Bernstein feels small messages should be authenticated;

0262 ///  and larger messages will be digested by the application.

0263 /// \details The accumulator is used for signing and verification.

0264 ///  The first 64-bytes of storage is reserved for the signature.

0265 ///  During signing the signature storage is unused. During

0266 ///  verification the first 64 bytes holds the signature. The

0267 ///  signature is provided by the PK_Verifier framework and the

0268 ///  call to PK_Signer::InputSignature. Member functions data()

0269 ///  and size() refer to the accumulated message. Member function

0270 ///  signature() refers to the signature with an implicit size of

0271 ///  SIGNATURE_LENGTH bytes.

0272 /// \details Applications which digest large messages, like an ISO

0273 ///  disk file, should take care because the design effectively

0274 ///  disgorges the format operation from the signing operation.

0275 ///  Put another way, be careful to ensure what you are signing is

0276 ///  is in fact a digest of the intended message, and not a different

0277 ///  message digest supplied by an attacker.

0278 struct ed25519_MessageAccumulator : public PK_MessageAccumulator
0279 {
0280     CRYPTOPP_CONSTANT(RESERVE_SIZE=2048+64);
0281     CRYPTOPP_CONSTANT(SIGNATURE_LENGTH=64);
0282 
0283     /// \brief Create a message accumulator

0284     ed25519_MessageAccumulator() {
0285         Restart();
0286     }
0287 
0288     /// \brief Create a message accumulator

0289     /// \details ed25519 does not use a RNG. You can safely use

0290     ///  NullRNG() because IsProbablistic returns false.

0291     ed25519_MessageAccumulator(RandomNumberGenerator &rng) {
0292         CRYPTOPP_UNUSED(rng); Restart();
0293     }
0294 
0295     /// \brief Add data to the accumulator

0296     /// \param msg pointer to the data to accumulate

0297     /// \param len the size of the data, in bytes

0298     void Update(const byte* msg, size_t len) {
0299         if (msg && len)
0300             m_msg.insert(m_msg.end(), msg, msg+len);
0301     }
0302 
0303     /// \brief Reset the accumulator

0304     void Restart() {
0305         m_msg.reserve(RESERVE_SIZE);
0306         m_msg.resize(SIGNATURE_LENGTH);
0307     }
0308 
0309     /// \brief Retrieve pointer to signature buffer

0310     /// \return pointer to signature buffer

0311     byte* signature() {
0312         return &m_msg[0];
0313     }
0314 
0315     /// \brief Retrieve pointer to signature buffer

0316     /// \return pointer to signature buffer

0317     const byte* signature() const {
0318         return &m_msg[0];
0319     }
0320 
0321     /// \brief Retrieve pointer to data buffer

0322     /// \return pointer to data buffer

0323     const byte* data() const {
0324         return &m_msg[0]+SIGNATURE_LENGTH;
0325     }
0326 
0327     /// \brief Retrieve size of data buffer

0328     /// \return size of the data buffer, in bytes

0329     size_t size() const {
0330         return m_msg.size()-SIGNATURE_LENGTH;
0331     }
0332 
0333 protected:
0334     // TODO: Find an equivalent Crypto++ structure.

0335     std::vector<byte, AllocatorWithCleanup<byte> > m_msg;
0336 };
0337 
0338 /// \brief Ed25519 private key

0339 /// \details ed25519PrivateKey is somewhat of a hack. It needed to

0340 ///  provide DL_PrivateKey interface to fit into the existing

0341 ///  framework, but it lacks a lot of the internals of a true

0342 ///  DL_PrivateKey. The missing pieces include GroupParameters

0343 ///  and Point, which provide the low level field operations

0344 ///  found in traditional implementations like NIST curves over

0345 ///  prime and binary fields.

0346 /// \details ed25519PrivateKey is also unusual because the

0347 ///  class members of interest are byte arrays and not Integers.

0348 ///  In addition, the byte arrays are little-endian meaning

0349 ///  LSB is at element 0 and the MSB is at element 31.

0350 ///  If you call GetPrivateExponent() then the little-endian byte

0351 ///  array is converted to a big-endian Integer() so it can be

0352 ///  returned the way a caller expects. And calling

0353 ///  SetPrivateExponent performs a similar internal conversion.

0354 /// \since Crypto++ 8.0

0355 struct ed25519PrivateKey : public PKCS8PrivateKey
0356 {
0357     /// \brief Size of the private key

0358     /// \details SECRET_KEYLENGTH is the size of the private key, in bytes.

0359     CRYPTOPP_CONSTANT(SECRET_KEYLENGTH = 32);
0360     /// \brief Size of the public key

0361     /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.

0362     CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32);
0363     /// \brief Size of the signature

0364     /// \details SIGNATURE_LENGTH is the size of the signature, in bytes.

0365     ///  ed25519 is a DL-based signature scheme. The signature is the

0366     ///  concatenation of <tt>r || s</tt>.

0367     CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64);
0368 
0369     virtual ~ed25519PrivateKey() {}
0370 
0371     // CryptoMaterial

0372     bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
0373     bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
0374     void AssignFrom(const NameValuePairs &source);
0375 
0376     // GroupParameters

0377     OID GetAlgorithmID() const {
0378         return m_oid.Empty() ? ASN1::Ed25519() : m_oid;
0379     }
0380 
0381     /// \brief DER encode ASN.1 object

0382     /// \param bt BufferedTransformation object

0383     /// \details Save() will write the OID associated with algorithm or scheme.

0384     ///  In the case of public and private keys, this function writes the

0385     ///  subjectPublicKeyInfo parts.

0386     /// \details The default OID is from RFC 8410 using <tt>id-Ed25519</tt>.

0387     ///  The default private key format is RFC 5208, which is the old format.

0388     ///  The old format provides the best interop, and keys will work

0389     ///  with OpenSSL.

0390     /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric

0391     ///  Key Packages</A>

0392     void Save(BufferedTransformation &bt) const {
0393         DEREncode(bt, 0);
0394     }
0395 
0396     /// \brief DER encode ASN.1 object

0397     /// \param bt BufferedTransformation object

0398     /// \param v1 flag indicating v1

0399     /// \details Save() will write the OID associated with algorithm or scheme.

0400     ///  In the case of public and private keys, this function writes the

0401     ///  subjectPublicKeyInfo parts.

0402     /// \details The default OID is from RFC 8410 using <tt>id-Ed25519</tt>.

0403     ///  The default private key format is RFC 5208.

0404     /// \details v1 means INTEGER 0 is written. INTEGER 0 means

0405     ///  RFC 5208 format, which is the old format. The old format provides

0406     ///  the best interop, and keys will work with OpenSSL. The other

0407     ///  option uses INTEGER 1. INTEGER 1 means RFC 5958 format,

0408     ///  which is the new format.

0409     /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric

0410     ///  Key Packages</A>

0411     void Save(BufferedTransformation &bt, bool v1) const {
0412         DEREncode(bt, v1 ? 0 : 1);
0413     }
0414 
0415     /// \brief BER decode ASN.1 object

0416     /// \param bt BufferedTransformation object

0417     /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric

0418     ///  Key Packages</A>

0419     void Load(BufferedTransformation &bt) {
0420         BERDecode(bt);
0421     }
0422 
0423     /// \brief Initializes a public key from this key

0424     /// \param pub reference to a public key

0425     void MakePublicKey(PublicKey &pub) const;
0426 
0427     // PKCS8PrivateKey

0428     void BERDecode(BufferedTransformation &bt);
0429     void DEREncode(BufferedTransformation &bt) const { DEREncode(bt, 0); }
0430     void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
0431     void DEREncodePrivateKey(BufferedTransformation &bt) const;
0432 
0433     /// \brief DER encode ASN.1 object

0434     /// \param bt BufferedTransformation object

0435     /// \param version indicates version

0436     /// \details DEREncode() will write the OID associated with algorithm or

0437     ///  scheme. In the case of public and private keys, this function writes

0438     ///  the subjectPublicKeyInfo parts.

0439     /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.

0440     ///  The default private key format is RFC 5208.

0441     /// \details The value of version is written as the INTEGER. INTEGER 0 means

0442     ///  RFC 5208 format, which is the old format. The old format provides

0443     ///  the best interop, and keys will work with OpenSSL. The INTEGER 1

0444     ///  means RFC 5958 format, which is the new format.

0445     void DEREncode(BufferedTransformation &bt, int version) const;
0446 
0447     /// \brief Determine if OID is valid for this object

0448     /// \details BERDecodeAndCheckAlgorithmID() parses the OID from

0449     ///  <tt>bt</tt> and determines if it valid for this object. The

0450     ///  problem in practice is there are multiple OIDs available to

0451     ///  denote curve25519 operations. The OIDs include an old GNU

0452     ///  OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves,

0453     ///  and OIDs specified in draft-ietf-curdle-pkix.

0454     /// \details By default BERDecodeAndCheckAlgorithmID() accepts an

0455     ///  OID set by the user, <tt>ASN1::curve25519()</tt> and <tt>ASN1::Ed25519()</tt>.

0456     ///  <tt>ASN1::curve25519()</tt> is generic and says "this key is valid for

0457     ///  curve25519 operations". <tt>ASN1::Ed25519()</tt> is specific and says

0458     ///  "this key is valid for ed25519 signing."

0459     void BERDecodeAndCheckAlgorithmID(BufferedTransformation& bt);
0460 
0461     // PKCS8PrivateKey

0462     void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params);
0463     void SetPrivateExponent(const byte x[SECRET_KEYLENGTH]);
0464     void SetPrivateExponent(const Integer &x);
0465     const Integer& GetPrivateExponent() const;
0466 
0467     /// \brief Test if a key has small order

0468     /// \param y public key

0469     bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const;
0470 
0471     /// \brief Retrieve private key byte array

0472     /// \return the private key byte array

0473     /// \details GetPrivateKeyBytePtr() is used by signing code to call ed25519_sign.

0474     const byte* GetPrivateKeyBytePtr() const {
0475         return m_sk.begin();
0476     }
0477 
0478     /// \brief Retrieve public key byte array

0479     /// \return the public key byte array

0480     /// \details GetPublicKeyBytePtr() is used by signing code to call ed25519_sign.

0481     const byte* GetPublicKeyBytePtr() const {
0482         return m_pk.begin();
0483     }
0484 
0485 protected:
0486     // Create a public key from a private key

0487     void SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const;
0488 
0489 protected:
0490     FixedSizeSecBlock<byte, SECRET_KEYLENGTH> m_sk;
0491     FixedSizeSecBlock<byte, PUBLIC_KEYLENGTH> m_pk;
0492     OID m_oid;  // preferred OID

0493     mutable Integer m_x;  // for DL_PrivateKey

0494 };
0495 
0496 /// \brief Ed25519 signature algorithm

0497 /// \since Crypto++ 8.0

0498 struct ed25519Signer : public PK_Signer
0499 {
0500     /// \brief Size of the private key

0501     /// \details SECRET_KEYLENGTH is the size of the private key, in bytes.

0502     CRYPTOPP_CONSTANT(SECRET_KEYLENGTH = 32);
0503     /// \brief Size of the public key

0504     /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.

0505     CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32);
0506     /// \brief Size of the signature

0507     /// \details SIGNATURE_LENGTH is the size of the signature, in bytes.

0508     ///  ed25519 is a DL-based signature scheme. The signature is the

0509     ///  concatenation of <tt>r || s</tt>.

0510     CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64);
0511     typedef Integer Element;
0512 
0513     virtual ~ed25519Signer() {}
0514 
0515     /// \brief Create an ed25519Signer object

0516     ed25519Signer() {}
0517 
0518     /// \brief Create an ed25519Signer object

0519     /// \param y public key

0520     /// \param x private key

0521     /// \details This constructor creates an ed25519Signer object using existing parameters.

0522     /// \note The public key is not validated.

0523     ed25519Signer(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]);
0524 
0525     /// \brief Create an ed25519Signer object

0526     /// \param x private key

0527     /// \details This constructor creates an ed25519Signer object using existing parameters.

0528     ///  The public key is calculated from the private key.

0529     ed25519Signer(const byte x[SECRET_KEYLENGTH]);
0530 
0531     /// \brief Create an ed25519Signer object

0532     /// \param y public key

0533     /// \param x private key

0534     /// \details This constructor creates an ed25519Signer object using existing parameters.

0535     /// \note The public key is not validated.

0536     ed25519Signer(const Integer &y, const Integer &x);
0537 
0538     /// \brief Create an ed25519Signer object

0539     /// \param x private key

0540     /// \details This constructor creates an ed25519Signer object using existing parameters.

0541     ///  The public key is calculated from the private key.

0542     ed25519Signer(const Integer &x);
0543 
0544     /// \brief Create an ed25519Signer object

0545     /// \param key PKCS8 private key

0546     /// \details This constructor creates an ed25519Signer object using existing private key.

0547     /// \note The keys are not validated.

0548     /// \since Crypto++ 8.6

0549     ed25519Signer(const PKCS8PrivateKey &key);
0550 
0551     /// \brief Create an ed25519Signer object

0552     /// \param rng RandomNumberGenerator derived class

0553     /// \details This constructor creates a new ed25519Signer using the random number generator.

0554     ed25519Signer(RandomNumberGenerator &rng);
0555 
0556     /// \brief Create an ed25519Signer object

0557     /// \param params public and private key

0558     /// \details This constructor creates an ed25519Signer object using existing parameters.

0559     ///  The <tt>params</tt> can be created with <tt>Save</tt>.

0560     /// \note The public key is not validated.

0561     ed25519Signer(BufferedTransformation &params);
0562 
0563     // DL_ObjectImplBase

0564     /// \brief Retrieves a reference to a Private Key

0565     /// \details AccessKey() retrieves a non-const reference to a private key.

0566     PrivateKey& AccessKey() { return m_key; }
0567     PrivateKey& AccessPrivateKey() { return m_key; }
0568 
0569     /// \brief Retrieves a reference to a Private Key

0570     /// \details AccessKey() retrieves a const reference to a private key.

0571     const PrivateKey& GetKey() const { return m_key; }
0572     const PrivateKey& GetPrivateKey() const { return m_key; }
0573 
0574     // DL_SignatureSchemeBase

0575     size_t SignatureLength() const { return SIGNATURE_LENGTH; }
0576     size_t MaxRecoverableLength() const { return 0; }
0577     size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const {
0578         CRYPTOPP_UNUSED(signatureLength); return 0;
0579     }
0580 
0581     bool IsProbabilistic() const { return false; }
0582     bool AllowNonrecoverablePart() const { return false; }
0583     bool RecoverablePartFirst() const { return false; }
0584 
0585     PK_MessageAccumulator* NewSignatureAccumulator(RandomNumberGenerator &rng) const {
0586         return new ed25519_MessageAccumulator(rng);
0587     }
0588 
0589     void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const {
0590         CRYPTOPP_UNUSED(messageAccumulator); CRYPTOPP_UNUSED(recoverableMessage);
0591         CRYPTOPP_UNUSED(recoverableMessageLength);
0592         throw NotImplemented("ed25519Signer: this object does not support recoverable messages");
0593     }
0594 
0595     size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const;
0596 
0597     /// \brief Sign a stream

0598     /// \param rng a RandomNumberGenerator derived class

0599     /// \param stream an std::istream derived class

0600     /// \param signature a block of bytes for the signature

0601     /// \return actual signature length

0602     /// \details SignStream() handles large streams. The Stream functions were added to

0603     ///  ed25519 for signing and verifying files that are too large for a memory allocation.

0604     ///  The functions are not present in other library signers and verifiers.

0605     /// \details ed25519 is a deterministic signature scheme. <tt>IsProbabilistic()</tt>

0606     ///  returns false and the random number generator can be <tt>NullRNG()</tt>.

0607     /// \pre <tt>COUNTOF(signature) == MaxSignatureLength()</tt>

0608     /// \since Crypto++ 8.1

0609     size_t SignStream (RandomNumberGenerator &rng, std::istream& stream, byte *signature) const;
0610 
0611 protected:
0612     ed25519PrivateKey m_key;
0613 };
0614 
0615 // ****************** ed25519 Verifier *********************** //

0616 
0617 /// \brief Ed25519 public key

0618 /// \details ed25519PublicKey is somewhat of a hack. It needed to

0619 ///  provide DL_PublicKey interface to fit into the existing

0620 ///  framework, but it lacks a lot of the internals of a true

0621 ///  DL_PublicKey. The missing pieces include GroupParameters

0622 ///  and Point, which provide the low level field operations

0623 ///  found in traditional implementations like NIST curves over

0624 ///  prime and binary fields.

0625 /// \details ed25519PublicKey is also unusual because the

0626 ///  class members of interest are byte arrays and not Integers.

0627 ///  In addition, the byte arrays are little-endian meaning

0628 ///  LSB is at element 0 and the MSB is at element 31.

0629 ///  If you call GetPublicElement() then the little-endian byte

0630 ///  array is converted to a big-endian Integer() so it can be

0631 ///  returned the way a caller expects. And calling

0632 ///  SetPublicElement() performs a similar internal conversion.

0633 /// \since Crypto++ 8.0

0634 struct ed25519PublicKey : public X509PublicKey
0635 {
0636     /// \brief Size of the public key

0637     /// \details PUBLIC_KEYLENGTH is the size of the public key, in bytes.

0638     CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32);
0639     typedef Integer Element;
0640 
0641     virtual ~ed25519PublicKey() {}
0642 
0643     OID GetAlgorithmID() const {
0644         return m_oid.Empty() ? ASN1::Ed25519() : m_oid;
0645     }
0646 
0647     /// \brief DER encode ASN.1 object

0648     /// \param bt BufferedTransformation object

0649     /// \details Save() will write the OID associated with algorithm or scheme.

0650     ///  In the case of public and private keys, this function writes the

0651     ///  subjectPublicKeyInfo parts.

0652     /// \details The default OID is from RFC 8410 using <tt>id-X25519</tt>.

0653     ///  The default private key format is RFC 5208, which is the old format.

0654     ///  The old format provides the best interop, and keys will work

0655     ///  with OpenSSL.

0656     void Save(BufferedTransformation &bt) const {
0657         DEREncode(bt);
0658     }
0659 
0660     /// \brief BER decode ASN.1 object

0661     /// \param bt BufferedTransformation object

0662     /// \sa <A HREF="http://tools.ietf.org/rfc/rfc5958.txt">RFC 5958, Asymmetric

0663     ///  Key Packages</A>

0664     void Load(BufferedTransformation &bt) {
0665         BERDecode(bt);
0666     }
0667 
0668     // X509PublicKey

0669     void BERDecode(BufferedTransformation &bt);
0670     void DEREncode(BufferedTransformation &bt) const;
0671     void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size);
0672     void DEREncodePublicKey(BufferedTransformation &bt) const;
0673 
0674     /// \brief Determine if OID is valid for this object

0675     /// \details BERDecodeAndCheckAlgorithmID() parses the OID from

0676     ///  <tt>bt</tt> and determines if it valid for this object. The

0677     ///  problem in practice is there are multiple OIDs available to

0678     ///  denote curve25519 operations. The OIDs include an old GNU

0679     ///  OID used by SSH, OIDs specified in draft-josefsson-pkix-newcurves,

0680     ///  and OIDs specified in draft-ietf-curdle-pkix.

0681     /// \details By default BERDecodeAndCheckAlgorithmID() accepts an

0682     ///  OID set by the user, <tt>ASN1::curve25519()</tt> and <tt>ASN1::Ed25519()</tt>.

0683     ///  <tt>ASN1::curve25519()</tt> is generic and says "this key is valid for

0684     ///  curve25519 operations". <tt>ASN1::Ed25519()</tt> is specific and says

0685     ///  "this key is valid for ed25519 signing."

0686     void BERDecodeAndCheckAlgorithmID(BufferedTransformation& bt);
0687 
0688     bool Validate(RandomNumberGenerator &rng, unsigned int level) const;
0689     bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
0690     void AssignFrom(const NameValuePairs &source);
0691 
0692     // DL_PublicKey

0693     void SetPublicElement(const byte y[PUBLIC_KEYLENGTH]);
0694     void SetPublicElement(const Element &y);
0695     const Element& GetPublicElement() const;
0696 
0697     /// \brief Retrieve public key byte array

0698     /// \return the public key byte array

0699     /// \details GetPublicKeyBytePtr() is used by signing code to call ed25519_sign.

0700     const byte* GetPublicKeyBytePtr() const {
0701         return m_pk.begin();
0702     }
0703 
0704 protected:
0705     FixedSizeSecBlock<byte, PUBLIC_KEYLENGTH> m_pk;
0706     OID m_oid;  // preferred OID

0707     mutable Integer m_y;  // for DL_PublicKey

0708 };
0709 
0710 /// \brief Ed25519 signature verification algorithm

0711 /// \since Crypto++ 8.0

0712 struct ed25519Verifier : public PK_Verifier
0713 {
0714     CRYPTOPP_CONSTANT(PUBLIC_KEYLENGTH = 32);
0715     CRYPTOPP_CONSTANT(SIGNATURE_LENGTH = 64);
0716     typedef Integer Element;
0717 
0718     virtual ~ed25519Verifier() {}
0719 
0720     /// \brief Create an ed25519Verifier object

0721     ed25519Verifier() {}
0722 
0723     /// \brief Create an ed25519Verifier object

0724     /// \param y public key

0725     /// \details This constructor creates an ed25519Verifier object using existing parameters.

0726     /// \note The public key is not validated.

0727     ed25519Verifier(const byte y[PUBLIC_KEYLENGTH]);
0728 
0729     /// \brief Create an ed25519Verifier object

0730     /// \param y public key

0731     /// \details This constructor creates an ed25519Verifier object using existing parameters.

0732     /// \note The public key is not validated.

0733     ed25519Verifier(const Integer &y);
0734 
0735     /// \brief Create an ed25519Verifier object

0736     /// \param key X509 public key

0737     /// \details This constructor creates an ed25519Verifier object using an existing public key.

0738     /// \note The public key is not validated.

0739     /// \since Crypto++ 8.6

0740     ed25519Verifier(const X509PublicKey &key);
0741 
0742     /// \brief Create an ed25519Verifier object

0743     /// \param params public and private key

0744     /// \details This constructor creates an ed25519Verifier object using existing parameters.

0745     ///  The <tt>params</tt> can be created with <tt>Save</tt>.

0746     /// \note The public key is not validated.

0747     ed25519Verifier(BufferedTransformation &params);
0748 
0749     /// \brief Create an ed25519Verifier object

0750     /// \param signer ed25519 signer object

0751     /// \details This constructor creates an ed25519Verifier object using existing parameters.

0752     ///  The <tt>params</tt> can be created with <tt>Save</tt>.

0753     /// \note The public key is not validated.

0754     ed25519Verifier(const ed25519Signer& signer);
0755 
0756     // DL_ObjectImplBase

0757     /// \brief Retrieves a reference to a Public Key

0758     /// \details AccessKey() retrieves a non-const reference to a public key.

0759     PublicKey& AccessKey() { return m_key; }
0760     PublicKey& AccessPublicKey() { return m_key; }
0761 
0762     /// \brief Retrieves a reference to a Public Key

0763     /// \details GetKey() retrieves a const reference to a public key.

0764     const PublicKey& GetKey() const { return m_key; }
0765     const PublicKey& GetPublicKey() const { return m_key; }
0766 
0767     // DL_SignatureSchemeBase

0768     size_t SignatureLength() const { return SIGNATURE_LENGTH; }
0769     size_t MaxRecoverableLength() const { return 0; }
0770     size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const {
0771         CRYPTOPP_UNUSED(signatureLength); return 0;
0772     }
0773 
0774     bool IsProbabilistic() const { return false; }
0775     bool AllowNonrecoverablePart() const { return false; }
0776     bool RecoverablePartFirst() const { return false; }
0777 
0778     ed25519_MessageAccumulator* NewVerificationAccumulator() const {
0779         return new ed25519_MessageAccumulator;
0780     }
0781 
0782     void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const {
0783         CRYPTOPP_ASSERT(signature != NULLPTR);
0784         CRYPTOPP_ASSERT(signatureLength == SIGNATURE_LENGTH);
0785         ed25519_MessageAccumulator& accum = static_cast<ed25519_MessageAccumulator&>(messageAccumulator);
0786         if (signature && signatureLength)
0787             std::memcpy(accum.signature(), signature, STDMIN((size_t)SIGNATURE_LENGTH, signatureLength));
0788     }
0789 
0790     bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
0791 
0792     /// \brief Check whether input signature is a valid signature for input message

0793     /// \param stream an std::istream derived class

0794     /// \param signature a pointer to the signature over the message

0795     /// \param signatureLen the size of the signature

0796     /// \return true if the signature is valid, false otherwise

0797     /// \details VerifyStream() handles large streams. The Stream functions were added to

0798     ///  ed25519 for signing and verifying files that are too large for a memory allocation.

0799     ///  The functions are not present in other library signers and verifiers.

0800     /// \since Crypto++ 8.1

0801     bool VerifyStream(std::istream& stream, const byte *signature, size_t signatureLen) const;
0802 
0803     DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const {
0804         CRYPTOPP_UNUSED(recoveredMessage); CRYPTOPP_UNUSED(messageAccumulator);
0805         throw NotImplemented("ed25519Verifier: this object does not support recoverable messages");
0806     }
0807 
0808 protected:
0809     ed25519PublicKey m_key;
0810 };
0811 
0812 /// \brief Ed25519 signature scheme

0813 /// \sa <A HREF="http://cryptopp.com/wiki/Ed25519">Ed25519</A> on the Crypto++ wiki.

0814 /// \since Crypto++ 8.0

0815 struct ed25519
0816 {
0817     /// \brief ed25519 Signer

0818     typedef ed25519Signer Signer;
0819     /// \brief ed25519 Verifier

0820     typedef ed25519Verifier Verifier;
0821 };
0822 
0823 NAMESPACE_END  // CryptoPP

0824 
0825 #endif  // CRYPTOPP_XED25519_H