18ANONYMOUS_NAMESPACE_BEGIN
22CRYPTOPP_ALIGN_DATA(16)
23const
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 }
50bool 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);
68ANONYMOUS_NAMESPACE_END
74x25519::
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);
86 Donna::curve25519_mult(m_pk, m_sk);
110 Donna::curve25519_mult(m_pk, m_sk);
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);
143void x25519::SecretToPublicKey(
byte y[PUBLIC_KEYLENGTH],
const byte x[SECRET_KEYLENGTH])
const
145 Donna::curve25519_mult(y, x);
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;
189 BERDecodeBitString(publicKey, subjectPublicKey, unusedBits);
195 generatePublicKey =
false;
196 publicKey.MessageEnd();
199 privateKeyInfo.MessageEnd();
201 if (generatePublicKey)
202 Donna::curve25519_mult(m_pk, m_sk);
215 DEREncodeUnsigned<word32>(privateKeyInfo, version);
219 algorithm.MessageEnd();
223 octetString.MessageEnd();
229 publicKey.MessageEnd();
232 privateKeyInfo.MessageEnd();
242 if (!privateKey.IsDefiniteLength())
250 if (parametersPresent)
253 privateKey.MessageEnd();
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);
363bool x25519::Agree(
byte *agreedValue,
const byte *privateKey,
const byte *otherPublicKey,
bool validateOtherPublicKey)
const
368 if (validateOtherPublicKey &&
IsSmallOrder(otherPublicKey))
371 return Donna::curve25519_mult(agreedValue, privateKey, otherPublicKey) == 0;
376void ed25519PrivateKey::SecretToPublicKey(
byte y[PUBLIC_KEYLENGTH],
const byte x[SECRET_KEYLENGTH])
const
378 int ret = Donna::ed25519_publickey(y, x);
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);
470 int ret = Donna::ed25519_publickey(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;
522 BERDecodeBitString(publicKey, subjectPublicKey, unusedBits);
528 generatePublicKey =
false;
529 publicKey.MessageEnd();
532 privateKeyInfo.MessageEnd();
534 if (generatePublicKey)
535 Donna::ed25519_publickey(m_pk, m_sk);
547 DEREncodeUnsigned<word32>(privateKeyInfo, version);
551 algorithm.MessageEnd();
555 octetString.MessageEnd();
561 publicKey.MessageEnd();
564 privateKeyInfo.MessageEnd();
574 if (!privateKey.IsDefiniteLength())
582 if (parametersPresent)
585 privateKey.MessageEnd();
593 privateKey.MessageEnd();
596void ed25519PrivateKey::SetPrivateExponent (
const byte x[SECRET_KEYLENGTH])
600 (
"DerivePublicKey",
true));
603void ed25519PrivateKey::SetPrivateExponent (
const Integer &x)
612 (
"DerivePublicKey",
true));
615const Integer& ed25519PrivateKey::GetPrivateExponent()
const
634 (
"DerivePublicKey",
true));
660 (
"DerivePublicKey",
true));
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();
764 publicKeyInfo.MessageEnd();
773 algorithm.MessageEnd();
777 publicKeyInfo.MessageEnd();
783 if (parametersPresent)
787 unsigned int unusedBits;
788 BERDecodeBitString(bt, subjectPublicKey, unusedBits);
803void ed25519PublicKey::SetPublicElement (
const byte y[PUBLIC_KEYLENGTH])
808void ed25519PublicKey::SetPublicElement (
const Integer &y)
818const Integer& ed25519PublicKey::GetPublicElement()
const
826 CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(level);
843 y.
Encode(by, PUBLIC_KEYLENGTH); std::reverse(by+0, by+PUBLIC_KEYLENGTH);
873 CRYPTOPP_UNUSED(signatureLen);
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Classes and functions for working with ANS.1 objects.
void BERDecodeError()
Raises a BERDecodeErr.
Used to pass byte array input as part of a NameValuePairs object.
const byte * begin() const
Pointer to the first byte in the memory block.
size_t size() const
Length of the memory block.
virtual void AssignFrom(const NameValuePairs &source)=0
Assign values to this object.
virtual void Load(BufferedTransformation &bt)
Loads a key from a BufferedTransformation.
virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms=g_nullNameValuePairs)
Generate a random key or crypto parameters.
Multiple precision integer with arithmetic operations.
size_t MinEncodedSize(Signedness sign=UNSIGNED) const
Minimum number of bytes to encode this integer.
@ UNSIGNED
an unsigned value
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Interface for retrieving values given their names.
bool GetValue(const char *name, T &value) const
Get a named value.
static void ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving)
Ensures an expected name and type is present.
void DEREncode(BufferedTransformation &bt) const
DER encode this OID.
Interface for accumulating messages to be signed or verified.
Interface for public keys.
Interface for random number generators.
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
virtual void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
virtual bool CanIncorporateEntropy() const
Determines if a generator can accept additional entropy.
iterator begin()
Provides an iterator pointing to the first element in the memory block.
size_type size() const
Provides the count of elements in the SecBlock.
x25519 with key validation
bool IsClamped(const byte x[SECRET_KEYLENGTH]) const
Determine if private key is clamped.
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode privateKey part of privateKeyInfo, without the OCTET STRING header
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
Derive agreed value.
static const int PUBLIC_KEYLENGTH
Size of the public key.
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
Generate private key in this domain.
bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
Test if a key has small order.
void ClampKey(byte x[SECRET_KEYLENGTH]) const
Clamp a private key.
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
void DEREncodePrivateKey(BufferedTransformation &bt) const
encode privateKey part of privateKeyInfo, without the OCTET STRING header
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
void Load(BufferedTransformation &bt)
BER decode ASN.1 object.
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
x25519()
Create a x25519 object.
static const int SECRET_KEYLENGTH
Size of the private key.
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
Generate a public key from a private key in this domain.
OID GetAlgorithmID() const
Get the Object Identifier.
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms)
Generate a random key or crypto parameters.
Abstract base classes that provide a uniform interface to this library.
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Implementation of BufferedTransformation's attachment interface.
Multiple precision integer with arithmetic operations.
#define COUNTOF(arr)
Counts elements in an array.
Crypto++ library namespace.
const char * Seed()
ConstByteArrayParameter.
const char * PublicElement()
Integer.
const char * GroupOID()
OID.
const char * PrivateExponent()
Integer.
ed25519 message accumulator
void Restart()
Reset the accumulator.
size_t size() const
Retrieve size of data buffer.
const byte * data() const
Retrieve pointer to data buffer.
byte * signature()
Retrieve pointer to signature buffer.
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
const byte * GetPrivateKeyBytePtr() const
Retrieve private key byte array.
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms)
Generate a random key or crypto parameters.
void MakePublicKey(PublicKey &pub) const
Initializes a public key from this key.
OID GetAlgorithmID() const
Retrieves the OID of the algorithm.
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
void DEREncodePrivateKey(BufferedTransformation &bt) const
encode privateKey part of privateKeyInfo, without the OCTET STRING header
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
Test if a key has small order.
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode privateKey part of privateKeyInfo, without the OCTET STRING header
static const int SECRET_KEYLENGTH
Size of the private key.
static const int PUBLIC_KEYLENGTH
Size of the public key.
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
static const int PUBLIC_KEYLENGTH
Size of the public key.
void BERDecodeAndCheckAlgorithmID(BufferedTransformation &bt)
Determine if OID is valid for this object.
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
void DEREncodePublicKey(BufferedTransformation &bt) const
encode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header
void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
decode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header
const byte * GetPublicKeyBytePtr() const
Retrieve public key byte array.
OID GetAlgorithmID() const
Retrieves the OID of the algorithm.
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Ed25519 signature algorithm.
ed25519Signer()
Create a ed25519Signer object.
PrivateKey & AccessPrivateKey()
Retrieves a reference to a Private Key.
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
Sign and restart messageAccumulator.
static const int PUBLIC_KEYLENGTH
Size of the public key.
static const int SECRET_KEYLENGTH
Size of the private key.
const PrivateKey & GetPrivateKey() const
Retrieves a reference to a Private Key.
static const int SIGNATURE_LENGTH
Size of the siganture.
size_t SignStream(RandomNumberGenerator &rng, std::istream &stream, byte *signature) const
Sign a stream.
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
Check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
PublicKey & AccessPublicKey()
Retrieves a reference to a Public Key.
ed25519Verifier()
Create a ed25519Verifier object.
bool VerifyStream(std::istream &stream, const byte *signature, size_t signatureLen) const
Check whether input signature is a valid signature for input message.
const PublicKey & GetPublicKey() const
Retrieves a reference to a Public Key.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Classes for x25519 and ed25519 operations.