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);
119 m_sk[0] &= 248; m_sk[31] &= 127; m_sk[31] |= 64;
130 x[0] &= 248; x[31] &= 127; x[31] |= 64;
136 return (x[0] & 248) == x[0] && (x[31] & 127) == x[31] && (x[31] | 64) == x[31];
141 return HasSmallOrder(y);
151 if (!m_oid.Empty() && m_oid != oid)
153 else if (oid == ASN1::curve25519() || oid == ASN1::X25519())
165 BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 1);
170 algorithm.MessageEnd();
174 octetString.MessageEnd();
177 bool generatePublicKey =
true;
178 if (privateKeyInfo.EndReached() ==
false )
184 unsigned int unusedBits;
191 generatePublicKey =
false;
192 publicKey.MessageEnd();
195 privateKeyInfo.MessageEnd();
197 if (generatePublicKey)
211 DEREncodeUnsigned<word32>(privateKeyInfo, version);
215 algorithm.MessageEnd();
219 octetString.MessageEnd();
225 publicKey.MessageEnd();
228 privateKeyInfo.MessageEnd();
238 if (!privateKey.IsDefiniteLength())
246 if (parametersPresent)
249 privateKey.MessageEnd();
257 privateKey.MessageEnd();
262 CRYPTOPP_UNUSED(rng);
266 if (level >= 1 &&
IsClamped(m_sk) ==
false)
305 *
reinterpret_cast<OID *
>(pValue) = m_oid;
339 m_sk[0] &= 248; m_sk[31] &= 127; m_sk[31] |= 64;
346 privateKey[0] &= 248; privateKey[31] &= 127; privateKey[31] |= 64;
351 CRYPTOPP_UNUSED(rng);
355 bool x25519::Agree(byte *agreedValue,
const byte *privateKey,
const byte *otherPublicKey,
bool validateOtherPublicKey)
const 360 if (validateOtherPublicKey &&
IsSmallOrder(otherPublicKey))
370 x[0] &= 248; x[31] &= 127; x[31] |= 64;
377 return (x[0] & 248) == x[0] && (x[31] & 127) == x[31] && (x[31] | 64) == x[31];
382 return HasSmallOrder(y);
387 CRYPTOPP_UNUSED(rng);
391 if (level >= 1 &&
IsClamped(m_sk) ==
false)
430 *
reinterpret_cast<OID *
>(pValue) = m_oid;
458 if (source.
GetValue(
"Clamp", clamp) && clamp ==
true)
472 m_sk[0] &= 248; m_sk[31] &= 127; m_sk[31] |= 64;
491 if (!m_oid.Empty() && m_oid != oid)
493 else if (oid == ASN1::curve25519() || oid == ASN1::Ed25519())
505 BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 1);
510 algorithm.MessageEnd();
514 octetString.MessageEnd();
517 bool generatePublicKey =
true;
518 if (privateKeyInfo.EndReached() ==
false )
524 unsigned int unusedBits;
531 generatePublicKey =
false;
532 publicKey.MessageEnd();
535 privateKeyInfo.MessageEnd();
537 if (generatePublicKey)
551 DEREncodeUnsigned<word32>(privateKeyInfo, version);
555 algorithm.MessageEnd();
559 octetString.MessageEnd();
565 publicKey.MessageEnd();
568 privateKeyInfo.MessageEnd();
578 if (!privateKey.IsDefiniteLength())
586 if (parametersPresent)
589 privateKey.MessageEnd();
597 privateKey.MessageEnd();
607 void ed25519PrivateKey::SetPrivateExponent (
const Integer &x)
612 x.
Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH);
619 const Integer& ed25519PrivateKey::GetPrivateExponent()
const 648 x.
Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH);
660 x.
Encode(bx, SECRET_KEYLENGTH); std::reverse(bx+0, bx+SECRET_KEYLENGTH);
669 AccessPrivateKey().GenerateRandom(rng);
674 AccessPrivateKey().Load(params);
689 return ret == 0 ? SIGNATURE_LENGTH : 0;
709 *
reinterpret_cast<OID *
>(pValue) = m_oid;
738 if (!m_oid.Empty() && m_oid != oid)
740 else if (oid == ASN1::curve25519() || oid == ASN1::Ed25519())
753 algorithm.MessageEnd();
755 BERDecodePublicKey(publicKeyInfo,
false, (
size_t)publicKeyInfo.RemainingLength());
757 publicKeyInfo.MessageEnd();
766 algorithm.MessageEnd();
768 DEREncodePublicKey(publicKeyInfo);
770 publicKeyInfo.MessageEnd();
776 if (parametersPresent)
780 unsigned int unusedBits;
798 std::memcpy(m_pk, y, PUBLIC_KEYLENGTH);
801 void ed25519PublicKey::SetPublicElement (
const Integer &y)
806 y.
Encode(by, PUBLIC_KEYLENGTH); std::reverse(by+0, by+PUBLIC_KEYLENGTH);
808 std::memcpy(m_pk, by, PUBLIC_KEYLENGTH);
811 const Integer& ed25519PublicKey::GetPublicElement()
const 819 CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(level);
836 y.
Encode(by, PUBLIC_KEYLENGTH); std::reverse(by+0, by+PUBLIC_KEYLENGTH);
844 AccessPublicKey().Load(params);
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
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...
void ClampKeys(byte y[PUBLIC_KEYLENGTH], byte x[SECRET_KEYLENGTH]) const
Clamp a private key.
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.
void ClampKeys(byte y[PUBLIC_KEYLENGTH], byte x[SECRET_KEYLENGTH]) const
Clamp a private key.
bool IsClamped(const byte x[SECRET_KEYLENGTH]) const
Determine if private key is clamped.
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.
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.
x25519(const byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH])
Create a x25519 object.
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.
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.