18 ANONYMOUS_NAMESPACE_BEGIN
22 CRYPTOPP_ALIGN_DATA(16)
23 const byte blacklist[][32] = {
24 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
26 { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
28 { 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a,
29 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 },
30 { 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b,
31 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 },
32 { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
33 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
34 { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
35 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
36 { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
37 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f },
38 { 0xcd, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a,
39 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x80 },
40 { 0x4c, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b,
41 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0xd7 },
42 { 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
43 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
44 { 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
45 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
46 { 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
47 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }
50 bool HasSmallOrder(
const byte y[32])
54 for (
size_t j = 0; j < 32; j++) {
55 for (
size_t i = 0; i <
COUNTOF(blacklist); i++) {
56 c[i] |= y[j] ^ blacklist[i][j];
61 for (
size_t i = 0; i <
COUNTOF(blacklist); i++) {
65 return (
bool)((k >> 8) & 1);
68 ANONYMOUS_NAMESPACE_END
74 x25519::
x25519(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH])
76 std::memcpy(m_pk, y, SECRET_KEYLENGTH);
77 std::memcpy(m_sk, x, PUBLIC_KEYLENGTH);
85 std::memcpy(m_sk, x, SECRET_KEYLENGTH);
120 SecretToPublicKey(m_pk, m_sk);
130 x[0] &= 248; x[31] &= 127; x[31] |= 64;
135 return (x[0] & 248) == x[0] && (x[31] & 127) == x[31] && (x[31] | 64) == x[31];
140 return HasSmallOrder(y);
155 if (!m_oid.Empty() && m_oid != oid)
157 else if (oid == ASN1::curve25519() || oid == ASN1::X25519())
169 BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 1);
174 algorithm.MessageEnd();
178 octetString.MessageEnd();
181 bool generatePublicKey =
true;
182 if (privateKeyInfo.EndReached() ==
false )
188 unsigned int unusedBits;
195 generatePublicKey =
false;
196 publicKey.MessageEnd();
199 privateKeyInfo.MessageEnd();
201 if (generatePublicKey)
215 DEREncodeUnsigned<word32>(privateKeyInfo, version);
219 algorithm.MessageEnd();
223 octetString.MessageEnd();
229 publicKey.MessageEnd();
232 privateKeyInfo.MessageEnd();
242 if (!privateKey.IsDefiniteLength())
245 size_t size = privateKey.
Get(m_sk, SECRET_KEYLENGTH);
246 if (size != SECRET_KEYLENGTH)
250 if (parametersPresent)
253 privateKey.MessageEnd();
260 privateKey.
Put(m_sk, SECRET_KEYLENGTH);
261 privateKey.MessageEnd();
266 CRYPTOPP_UNUSED(rng);
270 if (level >= 1 &&
IsClamped(m_sk) ==
false)
278 SecretToPublicKey(pk, m_sk);
309 *
reinterpret_cast<OID *
>(pValue) = m_oid;
336 if (source.
GetValue(
"DerivePublicKey", derive) && derive ==
true)
337 SecretToPublicKey(m_pk, m_sk);
348 SecretToPublicKey(m_pk, m_sk);
359 CRYPTOPP_UNUSED(rng);
360 SecretToPublicKey(publicKey, privateKey);
363 bool x25519::Agree(byte *agreedValue,
const byte *privateKey,
const byte *otherPublicKey,
bool validateOtherPublicKey)
const 368 if (validateOtherPublicKey &&
IsSmallOrder(otherPublicKey))
376 void ed25519PrivateKey::SecretToPublicKey(byte y[PUBLIC_KEYLENGTH],
const byte x[SECRET_KEYLENGTH])
const 384 return HasSmallOrder(y);
389 CRYPTOPP_UNUSED(rng);
398 SecretToPublicKey(pk, m_sk);
429 *
reinterpret_cast<OID *
>(pValue) = m_oid;
457 if (source.
GetValue(
"DerivePublicKey", derive) && derive ==
true)
458 SecretToPublicKey(m_pk, m_sk);
488 if (!m_oid.Empty() && m_oid != oid)
490 else if (oid == ASN1::curve25519() || oid == ASN1::Ed25519())
502 BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 1);
507 algorithm.MessageEnd();
511 octetString.MessageEnd();
514 bool generatePublicKey =
true;
515 if (privateKeyInfo.EndReached() ==
false )
521 unsigned int unusedBits;
528 generatePublicKey =
false;
529 publicKey.MessageEnd();
532 privateKeyInfo.MessageEnd();
534 if (generatePublicKey)
547 DEREncodeUnsigned<word32>(privateKeyInfo, version);
551 algorithm.MessageEnd();
555 octetString.MessageEnd();
561 publicKey.MessageEnd();
564 privateKeyInfo.MessageEnd();
574 if (!privateKey.IsDefiniteLength())
577 size_t size = privateKey.
Get(m_sk, SECRET_KEYLENGTH);
578 if (size != SECRET_KEYLENGTH)
582 if (parametersPresent)
585 privateKey.MessageEnd();
592 privateKey.
Put(m_sk, SECRET_KEYLENGTH);
593 privateKey.MessageEnd();
596 void ed25519PrivateKey::SetPrivateExponent (
const byte x[SECRET_KEYLENGTH])
600 (
"DerivePublicKey",
true));
603 void ed25519PrivateKey::SetPrivateExponent (
const Integer &x)
608 x.
Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH);
612 (
"DerivePublicKey",
true));
615 const Integer& ed25519PrivateKey::GetPrivateExponent()
const 634 (
"DerivePublicKey",
true));
642 SecByteBlock by(PUBLIC_KEYLENGTH), bx(SECRET_KEYLENGTH);
643 y.
Encode(by, PUBLIC_KEYLENGTH); std::reverse(by+0, by+PUBLIC_KEYLENGTH);
644 x.
Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH);
656 x.
Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH);
660 (
"DerivePublicKey",
true));
665 AccessPrivateKey().GenerateRandom(rng);
670 AccessPrivateKey().Load(params);
685 return ret == 0 ? SIGNATURE_LENGTH : 0;
696 return ret == 0 ? SIGNATURE_LENGTH : 0;
716 *
reinterpret_cast<OID *
>(pValue) = m_oid;
745 if (!m_oid.Empty() && m_oid != oid)
747 else if (oid == ASN1::curve25519() || oid == ASN1::Ed25519())
760 algorithm.MessageEnd();
762 BERDecodePublicKey(publicKeyInfo,
false, (
size_t)publicKeyInfo.RemainingLength());
764 publicKeyInfo.MessageEnd();
773 algorithm.MessageEnd();
775 DEREncodePublicKey(publicKeyInfo);
777 publicKeyInfo.MessageEnd();
783 if (parametersPresent)
787 unsigned int unusedBits;
803 void ed25519PublicKey::SetPublicElement (
const byte y[PUBLIC_KEYLENGTH])
805 std::memcpy(m_pk, y, PUBLIC_KEYLENGTH);
808 void ed25519PublicKey::SetPublicElement (
const Integer &y)
813 y.
Encode(by, PUBLIC_KEYLENGTH); std::reverse(by+0, by+PUBLIC_KEYLENGTH);
815 std::memcpy(m_pk, by, PUBLIC_KEYLENGTH);
818 const Integer& ed25519PublicKey::GetPublicElement()
const 826 CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(level);
843 y.
Encode(by, PUBLIC_KEYLENGTH); std::reverse(by+0, by+PUBLIC_KEYLENGTH);
851 AccessPublicKey().Load(params);
873 CRYPTOPP_UNUSED(signatureLen);
Used to pass byte array input as part of a NameValuePairs object.
virtual void AssignFrom(const NameValuePairs &source)=0
Assign values to this object.
x25519 with key validation
x25519()
Create a x25519 object.
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms)
Generate a random key or crypto parameters.
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
Check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
size_t size() const
Length of the memory block.
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
Abstract base classes that provide a uniform interface to this library.
void Restart()
Reset the accumulator.
size_t size() const
Retrieve size of data buffer.
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate a public key from a private key in this domain.
Interface for random number generators.
void MakePublicKey(PublicKey &pub) const
Initializes a public key from this key.
ed25519Verifier()
Create a ed25519Verifier object.
static const int SECRET_KEYLENGTH
Size of the private key.
void DEREncodePublicKey(BufferedTransformation &bt) const
encode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
byte order is little-endian
const char * PrivateExponent()
Integer.
size_t SignStream(RandomNumberGenerator &rng, std::istream &stream, byte *signature) const
Sign a stream.
int ed25519_sign(const byte *message, size_t messageLength, const byte secretKey[32], const byte publicKey[32], byte signature[64])
Creates a signature on a message.
size_t MinEncodedSize(Signedness sign=UNSIGNED) const
Minimum number of bytes to encode this integer.
void ClampKey(byte x[SECRET_KEYLENGTH]) const
Clamp a private key.
int curve25519_mult(byte publicKey[32], const byte secretKey[32])
Generate a public key.
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate private key in this domain.
const byte * data() const
Retrieve pointer to data buffer.
const byte * begin() const
Pointer to the first byte in the memory block.
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
void DEREncode(BufferedTransformation &bt) const
DER encode this OID.
const char * GroupOID()
OID.
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
static const int PUBLIC_KEYLENGTH
Size of the public key.
Multiple precision integer with arithmetic operations.
const PrivateKey & GetPrivateKey() const
Retrieves a reference to a Private Key.
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
int ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64])
Verifies a signature on a message.
const NameValuePairs & g_nullNameValuePairs
An empty set of name-value pairs.
virtual bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
#define COUNTOF(arr)
Counts elements in an array.
const char * Seed()
ConstByteArrayParameter.
Classes for x25519 and ed25519 operations.
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode privateKey part of privateKeyInfo, without the OCTET STRING header
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
void BERDecodeError()
Raises a BERDecodeErr.
Classes and functions for working with ANS.1 objects.
ed25519 message accumulator
iterator begin()
Provides an iterator pointing to the first element in the memory block.
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Implementation of BufferedTransformation's attachment interface.
Ed25519 signature algorithm.
Interface for accumulating messages to be signed or verified.
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
Sign and restart messageAccumulator.
bool IsClamped(const byte x[SECRET_KEYLENGTH]) const
Determine if private key is clamped.
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
static void ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving)
Ensures an expected name and type is present.
bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
Test if a key has small order.
OID GetAlgorithmID() const
Get the Object Identifier.
bool VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count)
Performs a near constant-time comparison of two equally sized buffers.
Multiple precision integer with arithmetic operations.
size_t BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
DER decode bit string.
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
Test if a key has small order.
Interface for public keys.
Crypto++ library namespace.
int ed25519_publickey(byte publicKey[32], const byte secretKey[32])
Creates a public key from a secret key.
bool GetValue(const char *name, T &value) const
Get a named value.
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
Derive agreed value.
ed25519Signer()
Create a ed25519Signer object.
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode privateKey part of privateKeyInfo, without the OCTET STRING header
const byte * GetPrivateKeyBytePtr() const
Retrieve private key byte array.
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms)
Generate a random key or crypto parameters.
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
bool VerifyStream(std::istream &stream, const byte *signature, size_t signatureLen) const
Check whether input signature is a valid signature for input message.
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
void DEREncodePrivateKey(BufferedTransformation &bt) const
encode privateKey part of privateKeyInfo, without the OCTET STRING header
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
const char * PublicElement()
Integer.
void DEREncodePrivateKey(BufferedTransformation &bt) const
encode privateKey part of privateKeyInfo, without the OCTET STRING header
void Load(BufferedTransformation &bt)
BER decode ASN.1 object.
size_type size() const
Provides the count of elements in the SecBlock.
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
virtual void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
size_t DEREncodeBitString(BufferedTransformation &bt, const byte *str, size_t strLen, unsigned int unusedBits=0)
DER encode bit string.
byte * signature()
Retrieve pointer to signature buffer.
Interface for retrieving values given their names.
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.