|
||||
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 ¶ms); 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 ¶ms); 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 ¶ms); 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 ¶ms); 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 ¶ms); 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
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |