Add SecretToPublicKey function for ed25519

Also remove IsClamped. Clamping occurs with ed25519, but it happens inside the Donna code. It is not needed elsewhere for ed25519.
pull/797/head
Jeffrey Walton 2019-02-07 15:00:00 -05:00
parent dde43de786
commit 4caa5ee724
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
3 changed files with 15 additions and 34 deletions

View File

@ -365,18 +365,12 @@ bool x25519::Agree(byte *agreedValue, const byte *privateKey, const byte *otherP
// ******************** ed25519 Signer ************************* // // ******************** ed25519 Signer ************************* //
void ed25519PrivateKey::ClampKeys(byte y[PUBLIC_KEYLENGTH], byte x[SECRET_KEYLENGTH]) const void ed25519PrivateKey::SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const
{ {
x[0] &= 248; x[31] &= 127; x[31] |= 64;
int ret = Donna::ed25519_publickey(y, x); int ret = Donna::ed25519_publickey(y, x);
CRYPTOPP_ASSERT(ret == 0); CRYPTOPP_UNUSED(ret); CRYPTOPP_ASSERT(ret == 0); CRYPTOPP_UNUSED(ret);
} }
bool ed25519PrivateKey::IsClamped(const byte x[SECRET_KEYLENGTH]) const
{
return (x[0] & 248) == x[0] && (x[31] & 127) == x[31] && (x[31] | 64) == x[31];
}
bool ed25519PrivateKey::IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const bool ed25519PrivateKey::IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
{ {
return HasSmallOrder(y); return HasSmallOrder(y);
@ -385,17 +379,14 @@ bool ed25519PrivateKey::IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const
bool ed25519PrivateKey::Validate(RandomNumberGenerator &rng, unsigned int level) const bool ed25519PrivateKey::Validate(RandomNumberGenerator &rng, unsigned int level) const
{ {
CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(rng);
CRYPTOPP_ASSERT(IsClamped(m_sk) == true);
CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false); CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false);
if (level >= 1 && IsClamped(m_sk) == false) if (level >= 1 && IsSmallOrder(m_pk) == true)
return false;
if (level >= 2 && IsSmallOrder(m_pk) == true)
return false; return false;
if (level >= 3) if (level >= 3)
{ {
SecByteBlock sk(m_sk, SECRET_KEYLENGTH), pk(PUBLIC_KEYLENGTH); SecByteBlock sk(m_sk, SECRET_KEYLENGTH), pk(PUBLIC_KEYLENGTH);
ClampKeys(pk, sk); SecretToPublicKey(pk, sk);
// Secret key is already clamped, bufs are equal // Secret key is already clamped, bufs are equal
if (VerifyBufsEqual(pk, m_pk, PUBLIC_KEYLENGTH) == false) if (VerifyBufsEqual(pk, m_pk, PUBLIC_KEYLENGTH) == false)
@ -454,11 +445,10 @@ void ed25519PrivateKey::AssignFrom(const NameValuePairs &source)
m_oid = oid; m_oid = oid;
} }
bool clamp = false; bool derive = false;
if (source.GetValue("Clamp", clamp) && clamp == true) if (source.GetValue("DerivePublicKey", derive) && derive == true)
ClampKeys(m_pk, m_sk); SecretToPublicKey(m_pk, m_sk);
CRYPTOPP_ASSERT(IsClamped(m_sk) == true);
CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false); CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false);
} }
@ -469,7 +459,6 @@ void ed25519PrivateKey::GenerateRandom(RandomNumberGenerator &rng, const NameVal
rng.IncorporateEntropy(seed.begin(), seed.size()); rng.IncorporateEntropy(seed.begin(), seed.size());
rng.GenerateBlock(m_sk, SECRET_KEYLENGTH); rng.GenerateBlock(m_sk, SECRET_KEYLENGTH);
m_sk[0] &= 248; m_sk[31] &= 127; m_sk[31] |= 64;
int ret = Donna::ed25519_publickey(m_pk, m_sk); int ret = Donna::ed25519_publickey(m_pk, m_sk);
CRYPTOPP_ASSERT(ret == 0); CRYPTOPP_UNUSED(ret); CRYPTOPP_ASSERT(ret == 0); CRYPTOPP_UNUSED(ret);
} }
@ -537,7 +526,6 @@ void ed25519PrivateKey::BERDecode(BufferedTransformation &bt)
if (generatePublicKey) if (generatePublicKey)
Donna::ed25519_publickey(m_pk, m_sk); Donna::ed25519_publickey(m_pk, m_sk);
CRYPTOPP_ASSERT(IsClamped(m_sk) == true);
CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false); CRYPTOPP_ASSERT(IsSmallOrder(m_pk) == false);
} }
@ -601,7 +589,7 @@ void ed25519PrivateKey::SetPrivateExponent (const byte x[SECRET_KEYLENGTH])
{ {
AssignFrom(MakeParameters AssignFrom(MakeParameters
(Name::PrivateExponent(), ConstByteArrayParameter(x, SECRET_KEYLENGTH)) (Name::PrivateExponent(), ConstByteArrayParameter(x, SECRET_KEYLENGTH))
("Clamp", true)); ("DerivePublicKey", true));
} }
void ed25519PrivateKey::SetPrivateExponent (const Integer &x) void ed25519PrivateKey::SetPrivateExponent (const Integer &x)
@ -613,7 +601,7 @@ void ed25519PrivateKey::SetPrivateExponent (const Integer &x)
AssignFrom(MakeParameters AssignFrom(MakeParameters
(Name::PrivateExponent(), ConstByteArrayParameter(bx, SECRET_KEYLENGTH, false)) (Name::PrivateExponent(), ConstByteArrayParameter(bx, SECRET_KEYLENGTH, false))
("Clamp", true)); ("DerivePublicKey", true));
} }
const Integer& ed25519PrivateKey::GetPrivateExponent() const const Integer& ed25519PrivateKey::GetPrivateExponent() const
@ -635,7 +623,7 @@ ed25519Signer::ed25519Signer(const byte x[SECRET_KEYLENGTH])
{ {
AccessPrivateKey().AssignFrom(MakeParameters AccessPrivateKey().AssignFrom(MakeParameters
(Name::PrivateExponent(), ConstByteArrayParameter(x, SECRET_KEYLENGTH, false)) (Name::PrivateExponent(), ConstByteArrayParameter(x, SECRET_KEYLENGTH, false))
("Clamp", true)); ("DerivePublicKey", true));
} }
ed25519Signer::ed25519Signer(const Integer &y, const Integer &x) ed25519Signer::ed25519Signer(const Integer &y, const Integer &x)
@ -661,7 +649,7 @@ ed25519Signer::ed25519Signer(const Integer &x)
AccessPrivateKey().AssignFrom(MakeParameters AccessPrivateKey().AssignFrom(MakeParameters
(Name::PrivateExponent(), ConstByteArrayParameter(bx, SECRET_KEYLENGTH, false)) (Name::PrivateExponent(), ConstByteArrayParameter(bx, SECRET_KEYLENGTH, false))
("Clamp", true)); ("DerivePublicKey", true));
} }
ed25519Signer::ed25519Signer(RandomNumberGenerator &rng) ed25519Signer::ed25519Signer(RandomNumberGenerator &rng)

View File

@ -452,17 +452,6 @@ struct ed25519PrivateKey : public PKCS8PrivateKey
void SetPrivateExponent(const Integer &x); void SetPrivateExponent(const Integer &x);
const Integer& GetPrivateExponent() const; const Integer& GetPrivateExponent() const;
/// \brief Clamp a private key
/// \param y public key
/// \param x private key
/// \details ClampKeys() clamps a private key and then regenerates the
/// public key from the private key.
void ClampKeys(byte y[PUBLIC_KEYLENGTH], byte x[SECRET_KEYLENGTH]) const;
/// \brief Determine if private key is clamped
/// \param x private key
bool IsClamped(const byte x[SECRET_KEYLENGTH]) const;
/// \brief Test if a key has small order /// \brief Test if a key has small order
/// \param y public key /// \param y public key
bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const; bool IsSmallOrder(const byte y[PUBLIC_KEYLENGTH]) const;
@ -481,6 +470,10 @@ struct ed25519PrivateKey : public PKCS8PrivateKey
return m_pk.begin(); return m_pk.begin();
} }
protected:
// Create a public key from a private key
void SecretToPublicKey(byte y[PUBLIC_KEYLENGTH], const byte x[SECRET_KEYLENGTH]) const;
protected: protected:
FixedSizeSecBlock<byte, SECRET_KEYLENGTH> m_sk; FixedSizeSecBlock<byte, SECRET_KEYLENGTH> m_sk;
FixedSizeSecBlock<byte, PUBLIC_KEYLENGTH> m_pk; FixedSizeSecBlock<byte, PUBLIC_KEYLENGTH> m_pk;