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, PUBLIC_KEYLENGTH);
77 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);
143void x25519::SecretToPublicKey(
byte y[PUBLIC_KEYLENGTH],
const byte x[SECRET_KEYLENGTH])
const
157 if (!m_oid.
Empty() && m_oid != oid)
159 else if (oid == ASN1::curve25519() || oid == ASN1::X25519() ||
160 oid ==
OID(1)+3+6+1+4+1+3029+1+5)
172 BERDecodeUnsigned<word32>(privateKeyInfo, version,
INTEGER, 0, 1);
177 algorithm.MessageEnd();
184 bool generatePublicKey =
true;
191 unsigned int unusedBits;
198 generatePublicKey =
false;
204 if (generatePublicKey)
218 DEREncodeUnsigned<word32>(privateKeyInfo, version);
222 algorithm.MessageEnd();
253 if (parametersPresent)
269 CRYPTOPP_UNUSED(rng);
273 if (level >= 1 &&
IsClamped(m_sk) ==
false)
281 SecretToPublicKey(pk, m_sk);
312 *
reinterpret_cast<OID *
>(pValue) = m_oid;
339 if (source.
GetValue(
"DerivePublicKey", derive) && derive ==
true)
340 SecretToPublicKey(m_pk, m_sk);
351 SecretToPublicKey(m_pk, m_sk);
362 CRYPTOPP_UNUSED(rng);
363 SecretToPublicKey(publicKey, privateKey);
366bool x25519::Agree(
byte *agreedValue,
const byte *privateKey,
const byte *otherPublicKey,
bool validateOtherPublicKey)
const
371 if (validateOtherPublicKey &&
IsSmallOrder(otherPublicKey))
379void ed25519PrivateKey::SecretToPublicKey(
byte y[PUBLIC_KEYLENGTH],
const byte x[SECRET_KEYLENGTH])
const
387 return HasSmallOrder(y);
392 CRYPTOPP_UNUSED(rng);
401 SecretToPublicKey(pk, m_sk);
432 *
reinterpret_cast<OID *
>(pValue) = m_oid;
460 if (source.
GetValue(
"DerivePublicKey", derive) && derive ==
true)
461 SecretToPublicKey(m_pk, m_sk);
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();
517 bool generatePublicKey =
true;
524 unsigned int unusedBits;
531 generatePublicKey =
false;
537 if (generatePublicKey)
550 DEREncodeUnsigned<word32>(privateKeyInfo, version);
554 algorithm.MessageEnd();
585 if (parametersPresent)
599void ed25519PrivateKey::SetPrivateExponent (
const byte x[SECRET_KEYLENGTH])
603 (
"DerivePublicKey",
true));
606void ed25519PrivateKey::SetPrivateExponent (
const Integer &x)
615 (
"DerivePublicKey",
true));
618const Integer& ed25519PrivateKey::GetPrivateExponent()
const
637 (
"DerivePublicKey",
true));
663 (
"DerivePublicKey",
true));
727 *
reinterpret_cast<OID *
>(pValue) = m_oid;
756 if (!m_oid.
Empty() && m_oid != oid)
758 else if (oid == ASN1::curve25519() || oid == ASN1::Ed25519())
771 algorithm.MessageEnd();
784 algorithm.MessageEnd();
794 if (parametersPresent)
798 unsigned int unusedBits;
814void ed25519PublicKey::SetPublicElement (
const byte y[PUBLIC_KEYLENGTH])
819void ed25519PublicKey::SetPublicElement (
const Integer &y)
829const Integer& ed25519PublicKey::GetPublicElement()
const
837 CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(level);
854 y.
Encode(by, PUBLIC_KEYLENGTH); std::reverse(by+0, by+PUBLIC_KEYLENGTH);
892 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.
CRYPTOPP_DLL size_t BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
DER decode bit string.
CRYPTOPP_DLL size_t DEREncodeBitString(BufferedTransformation &bt, const byte *str, size_t strLen, unsigned int unusedBits=0)
DER encode bit string.
@ CONSTRUCTED
ASN.1 Constructed flag.
@ CONTEXT_SPECIFIC
ASN.1 Context specific class.
@ OCTET_STRING
ASN.1 Octet string.
void BERDecodeError()
Raises a BERDecodeErr.
void Save(BufferedTransformation &bt) const
DER encode ASN.1 object.
bool EndReached() const
Determine end of stream.
lword RemainingLength() const
Determine remaining length.
bool IsDefiniteLength() const
Determine length encoding.
void MessageEnd()
Signals the end of messages to the object.
Data structure used to store byte strings.
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.
void MessageEnd()
Signals the end of messages to the object.
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 CRYPTOPP_DLL 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.
bool Empty() const
Determine if OID is empty.
Interface for accumulating messages to be signed or verified.
Encodes and Decodes privateKeyInfo.
Interface for public keys.
Interface for random number generators.
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.
virtual void GenerateBlock(byte *output, size_t size)
Generate random array of bytes.
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.
Encodes and decodes subjectPublicKeyInfo.
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.
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.
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.
unsigned char byte
8-bit unsigned datatype
unsigned int word32
32-bit unsigned datatype
Abstract base classes that provide a uniform interface to this library.
const NameValuePairs & g_nullNameValuePairs
An empty set of name-value pairs.
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
int ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64])
Verifies a signature on a message.
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.
int ed25519_publickey(byte publicKey[32], const byte secretKey[32])
Creates a public key from a secret key.
int curve25519_mult(byte publicKey[32], const byte secretKey[32])
Generate a public key.
Implementation of BufferedTransformation's attachment interface.
Multiple precision integer with arithmetic operations.
#define COUNTOF(arr)
Counts elements in an array.
CRYPTOPP_DLL bool VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count)
Performs a near constant-time comparison of two equally sized buffers.
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.
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.
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.
void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size)
Decode subjectPublicKey part of subjectPublicKeyInfo.
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 an 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 signature.
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 an 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.