From d83fc3181be099fc0fe91f4c5532546c28cc58c1 Mon Sep 17 00:00:00 2001 From: orignal Date: Sat, 7 Jan 2017 21:20:09 -0500 Subject: [PATCH] EdDSA keys compatible with Java --- Identity.cpp | 2 +- Signature.cpp | 14 ++++++++++++-- Signature.h | 3 ++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Identity.cpp b/Identity.cpp index 19c1a240..4e9bee63 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -509,7 +509,7 @@ namespace data m_Signer.reset (new i2p::crypto::RSASHA5124096Signer (m_SigningPrivateKey)); break; case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: - m_Signer.reset (new i2p::crypto::EDDSA25519Signer (m_SigningPrivateKey)); + m_Signer.reset (new i2p::crypto::EDDSA25519Signer (m_SigningPrivateKey, m_Public->GetStandardIdentity ().certificate - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH)); break; default: LogPrint (eLogError, "Identity: Signing key type ", (int)m_Public->GetSigningKeyType (), " is not supported"); diff --git a/Signature.cpp b/Signature.cpp index 11fc8600..c38b1333 100644 --- a/Signature.cpp +++ b/Signature.cpp @@ -467,17 +467,27 @@ namespace crypto return GetEd25519 ()->Verify (m_PublicKey, digest, signature); } - EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey) + EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) { // expand key SHA512 (signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH, m_ExpandedPrivateKey); m_ExpandedPrivateKey[0] &= 0xF8; // drop last 3 bits - m_ExpandedPrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] &= 0x1F; // drop first 3 bits + m_ExpandedPrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] &= 0x3F; // drop first 2 bits m_ExpandedPrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] |= 0x40; // set second bit + // generate and encode public key BN_CTX * ctx = BN_CTX_new (); auto publicKey = GetEd25519 ()->GeneratePublicKey (m_ExpandedPrivateKey, ctx); GetEd25519 ()->EncodePublicKey (publicKey, m_PublicKeyEncoded, ctx); + + if (signingPublicKey && memcmp (m_PublicKeyEncoded, signingPublicKey, EDDSA25519_PUBLIC_KEY_LENGTH)) + { + // keys don't match, it means older key with 0x1F + LogPrint (eLogWarning, "Older EdDSA key detected"); + m_ExpandedPrivateKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] &= 0xDF; // drop third bit + publicKey = GetEd25519 ()->GeneratePublicKey (m_ExpandedPrivateKey, ctx); + GetEd25519 ()->EncodePublicKey (publicKey, m_PublicKeyEncoded, ctx); + } BN_CTX_free (ctx); } diff --git a/Signature.h b/Signature.h index a4f37980..c2618f91 100644 --- a/Signature.h +++ b/Signature.h @@ -424,7 +424,8 @@ namespace crypto { public: - EDDSA25519Signer (const uint8_t * signingPrivateKey); + EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); + // we pass signingPublicKey to check if it matches private key void Sign (const uint8_t * buf, int len, uint8_t * signature) const; const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; };