diff --git a/Identity.cpp b/Identity.cpp index 3b64b563..9dc96d01 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -470,6 +470,9 @@ namespace data case SIGNING_KEY_TYPE_RSA_SHA512_4096: m_Signer = new i2p::crypto::RSASHA5124096Signer (m_SigningPrivateKey); break; + case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: + m_Signer = new i2p::crypto::EDDSA25519Signer (m_SigningPrivateKey); + break; default: LogPrint ("Signing key type ", (int)m_Public.GetSigningKeyType (), " is not supported"); } diff --git a/Signature.cpp b/Signature.cpp index 20f0c289..603ba6eb 100644 --- a/Signature.cpp +++ b/Signature.cpp @@ -1,3 +1,4 @@ +#include #include #include #include "Log.h" @@ -18,11 +19,22 @@ namespace crypto // 2^252 + 27742317777372353535851937790883648493 d = CryptoPP::Integer (-121665) * CryptoPP::Integer (121666).InverseMod (q); // -121665/121666 I = a_exp_b_mod_c (CryptoPP::Integer::Two (), (q - CryptoPP::Integer::One ()).DividedBy (4), q); + B = DecodePoint (CryptoPP::Integer (4)*CryptoPP::Integer (5).InverseMod (q)); + } + + CryptoPP::ECP::Point DecodePublicKey (const uint8_t * key) const + { + return DecodePoint (CryptoPP::Integer (key, 32)); + } + + CryptoPP::ECP::Point GeneratePublicKey (const uint8_t * privateKey) const + { + return Mul (B, CryptoPP::Integer (privateKey, 32)); } private: - CryptoPP::ECP::Point Sum (const CryptoPP::ECP::Point& p1, const CryptoPP::ECP::Point& p2) + CryptoPP::ECP::Point Sum (const CryptoPP::ECP::Point& p1, const CryptoPP::ECP::Point& p2) const { CryptoPP::Integer m = d*p1.x*p2.x*p1.y*p2.y, x = a_times_b_mod_c (p1.x*p2.y + p2.x*p1.y, (CryptoPP::Integer::One() + m).InverseMod (q), q), @@ -30,7 +42,7 @@ namespace crypto return CryptoPP::ECP::Point {x, y}; } - CryptoPP::ECP::Point Mul (const CryptoPP::ECP::Point& p, const CryptoPP::Integer& e) + CryptoPP::ECP::Point Mul (const CryptoPP::ECP::Point& p, const CryptoPP::Integer& e) const { CryptoPP::ECP::Point res {0, 1}; if (!e.IsZero ()) @@ -45,13 +57,13 @@ namespace crypto return res; } - bool IsOnCurve (const CryptoPP::ECP::Point& p) + bool IsOnCurve (const CryptoPP::ECP::Point& p) const { auto x2 = p.x.Squared(), y2 = p.y.Squared (); return (y2 - x2 - CryptoPP::Integer::One() - d*x2*y2).Modulo (q).IsZero (); } - CryptoPP::Integer RecoverX (const CryptoPP::Integer& y) + CryptoPP::Integer RecoverX (const CryptoPP::Integer& y) const { auto y2 = y.Squared (); auto xx = (y2 - CryptoPP::Integer::One())*(d*y2 + CryptoPP::Integer::One()).InverseMod (q); @@ -62,7 +74,7 @@ namespace crypto return x; } - CryptoPP::ECP::Point DecodePoint (const CryptoPP::Integer& y) + CryptoPP::ECP::Point DecodePoint (const CryptoPP::Integer& y) const { auto x = RecoverX (y); CryptoPP::ECP::Point p {x, y}; @@ -77,11 +89,31 @@ namespace crypto private: CryptoPP::Integer q, l, d, I; + CryptoPP::ECP::Point B; // base point }; + static std::unique_ptr g_Ed25519; + std::unique_ptr& GetEd25519 () + { + if (!g_Ed25519) + g_Ed25519.reset (new Ed25519 ()); + return g_Ed25519; + } + + + EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey): + m_PublicKey (GetEd25519 ()->DecodePublicKey (signingKey)) + { + } + bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const { return true; // TODO: + } + + void EDDSA25519Signer::Sign (CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf, int len, uint8_t * signature) const + { + // TODO } } } diff --git a/Signature.h b/Signature.h index 3aa739e4..acfaa62f 100644 --- a/Signature.h +++ b/Signature.h @@ -419,14 +419,24 @@ namespace crypto { public: - EDDSA25519Verifier (const uint8_t * signingKey) - { - } - + EDDSA25519Verifier (const uint8_t * signingKey); bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; size_t GetPublicKeyLen () const { return EDDSA25519_PUBLIC_KEY_LENGTH; }; - size_t GetSignatureLen () const { return EDDSA25519_SIGNATURE_LENGTH; }; + size_t GetSignatureLen () const { return EDDSA25519_SIGNATURE_LENGTH; }; + + private: + + CryptoPP::ECP::Point m_PublicKey; + }; + + class EDDSA25519Signer: public Signer + { + public: + + EDDSA25519Signer (const uint8_t * signingPrivateKey) {}; + + void Sign (CryptoPP::RandomNumberGenerator& rnd, const uint8_t * buf, int len, uint8_t * signature) const; }; } }