diff --git a/Crypto.cpp b/Crypto.cpp index 04126cb6..9e328fd0 100644 --- a/Crypto.cpp +++ b/Crypto.cpp @@ -797,15 +797,6 @@ namespace crypto m_OpenSSLMutexes[type]->unlock (); } }*/ - - - uint8_t * GOSTR3411 (const uint8_t * buf, size_t len, uint8_t * digest) - { - // TODO: implement actual GOST R 34.11 - // SHA-256 is used for testing only - SHA256 (buf, len, digest); - return digest; - } void InitCrypto (bool precomputation, bool withGost) diff --git a/Crypto.h b/Crypto.h index 691bb716..f55e1bd7 100644 --- a/Crypto.h +++ b/Crypto.h @@ -278,9 +278,6 @@ namespace crypto CBCDecryption m_LayerDecryption; #endif }; - -// GOST - uint8_t * GOSTR3411 (const uint8_t * buf, size_t len, uint8_t * digest); // hash void InitCrypto (bool precomputation, bool withGost = false); void TerminateCrypto (); diff --git a/Gost.cpp b/Gost.cpp index 7d9db0f8..63625baa 100644 --- a/Gost.cpp +++ b/Gost.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "Gost.h" @@ -6,6 +7,9 @@ namespace i2p { namespace crypto { + +// GOST R 34.10 + GOSTR3410Curve::GOSTR3410Curve (BIGNUM * a, BIGNUM * b, BIGNUM * p, BIGNUM * q, BIGNUM * x, BIGNUM * y) { BN_CTX * ctx = BN_CTX_new (); @@ -117,7 +121,23 @@ namespace crypto "9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9", "0", "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67" - } // C + }, // C + { + "C2173F1513981673AF4892C23035A27CE25E2013BF95AA33B22C656F277E7335", + "295F9BAE7428ED9CCC20E7C359A9D41A22FCCD9108E17BF7BA9337A6F8AE9513", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", + "400000000000000000000000000000000FD8CDDFC87B6635C115AF556C360C67", + "91E38443A5E82C0D880923425712B2BB658B9196932E02C78B2582FE742DAA28", + "32879423AB1A0375895786C4BB46E9565FDE0B5344766740AF268ADB32322E5C" + }, // tc26-2012-paramSetA-256 + { + "DC9203E514A721875485A529D2C722FB187BC8980EB866644DE41C68E143064546E861C0E2C9EDD92ADE71F46FCF50FF2AD97F951FDA9F2A2EB6546F39689BD3", + "B4C4EE28CEBC6C2C8AC12952CF37F16AC7EFB6A9F69F4B57FFDA2E4F0DE5ADE038CBC2FFF719D2C18DE0284B8BFEF3B52B8CC7A5F5BF0A3C8D2319A5312557E1", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7", + "3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC98CDBA46506AB004C33A9FF5147502CC8EDA9E7A769A12694623CEF47F023ED", + "E2E31EDFC23DE7BDEBE241CE593EF5DE2295B7A9CBAEF021D385F7074CEA043AA27272A7AE602BF2A7B9033DB9ED3610C6FB85487EAE97AAC5BC7928C1950148", + "F5CE40D95B5EB899ABBCCFF5911CB8577939804D6527378B8C108C3D2090FF9BE18E2D33E3021ED27EF32D85822423B6304F726AA854BAE07D0396E9A9ADDC40F" + } // tc26-2012-paramSetC-256 }; BIGNUM * a = nullptr, * b = nullptr, * p = nullptr, * q =nullptr, * x = nullptr, * y = nullptr; @@ -145,6 +165,5 @@ namespace crypto } return g_GOSTR3410Curves[paramSet]; } - } } diff --git a/Gost.h b/Gost.h index f287219f..62a8aea1 100644 --- a/Gost.h +++ b/Gost.h @@ -13,12 +13,16 @@ namespace crypto enum GOSTR3410ParamSet { + // GOST R 34.10-2001 eGOSTR3410CryptoProA = 0, // 1.2.643.2.2.35.1 eGOSTR3410CryptoProB, // 1.2.643.2.2.35.2 eGOSTR3410CryptoProC, // 1.2.643.2.2.35.3 + // XchA = A, XchB = C //eGOSTR3410CryptoProXchA, // 1.2.643.2.2.36.0 //eGOSTR3410CryptoProXchB, // 1.2.643.2.2.36.1 - // XchA = A, XchB = C + // GOST R 34.10-2012 + eGOSTR3410tc26paramSetA256, // 1.2.643.7.1.2.1.1.1 + eGOSTR3410tc26paramSetC512, // 1.2.643.7.1.2.1.2.3 eGOSTR3410NumParamSets }; @@ -44,4 +48,4 @@ namespace crypto } } -#endif \ No newline at end of file +#endif diff --git a/Signature.cpp b/Signature.cpp index bcb451f2..7571760a 100644 --- a/Signature.cpp +++ b/Signature.cpp @@ -492,57 +492,6 @@ namespace crypto { GetEd25519 ()->Sign (m_ExpandedPrivateKey, m_PublicKeyEncoded, buf, len, signature); } - -//---------------------------------------------- -// GOST - - GOSTR3410Verifier::GOSTR3410Verifier (GOSTR3410ParamSet paramSet, const uint8_t * signingKey): - m_ParamSet (paramSet) - { - BIGNUM * x = BN_bin2bn (signingKey, GOSTR3410_PUBLIC_KEY_LENGTH/2, NULL); - BIGNUM * y = BN_bin2bn (signingKey + GOSTR3410_PUBLIC_KEY_LENGTH/2, GOSTR3410_PUBLIC_KEY_LENGTH/2, NULL); - m_PublicKey = GetGOSTR3410Curve (m_ParamSet)->CreatePoint (x, y); - BN_free (x); BN_free (y); - } - - bool GOSTR3410Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const - { - uint8_t digest[32]; - GOSTR3411 (buf, len, digest); - BIGNUM * d = BN_bin2bn (digest, 32, nullptr); - BIGNUM * r = BN_bin2bn (signature, GetSignatureLen ()/2, NULL); - BIGNUM * s = BN_bin2bn (signature + GetSignatureLen ()/2, GetSignatureLen ()/2, NULL); - bool ret = GetGOSTR3410Curve (m_ParamSet)->Verify (m_PublicKey, d, r, s); - BN_free (d); BN_free (r); BN_free (s); - return ret; - } - - void GOSTR3410Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const - { - uint8_t digest[32]; - GOSTR3411 (buf, len, digest); - BIGNUM * d = BN_bin2bn (digest, 32, nullptr); - BIGNUM * r = BN_new (), * s = BN_new (); - GetGOSTR3410Curve (m_ParamSet)->Sign (m_PrivateKey, d, r, s); - bn2buf (r, signature, GOSTR3410_SIGNATURE_LENGTH/2); - bn2buf (s, signature + GOSTR3410_SIGNATURE_LENGTH/2, GOSTR3410_SIGNATURE_LENGTH/2); - BN_free (d); BN_free (r); BN_free (s); - } - - void CreateGOSTR3410RandomKeys (GOSTR3410ParamSet paramSet, uint8_t * signingPrivateKey, uint8_t * signingPublicKey) - { - RAND_bytes (signingPrivateKey, GOSTR3410_PUBLIC_KEY_LENGTH/2); - BIGNUM * priv = BN_bin2bn (signingPrivateKey, GOSTR3410_PUBLIC_KEY_LENGTH/2, nullptr); - const auto& curve = GetGOSTR3410Curve (paramSet); - auto pub = curve->MulP (priv); - BN_free (priv); - BIGNUM * x = BN_new (), * y = BN_new (); - curve->GetXY (pub, x, y); - EC_POINT_free (pub); - bn2buf (x, signingPublicKey, GOSTR3410_PUBLIC_KEY_LENGTH/2); - bn2buf (y, signingPublicKey + GOSTR3410_PUBLIC_KEY_LENGTH/2, GOSTR3410_PUBLIC_KEY_LENGTH/2); - BN_free (x); BN_free (y); - } } } diff --git a/Signature.h b/Signature.h index 91f0e66b..62a36cd3 100644 --- a/Signature.h +++ b/Signature.h @@ -452,10 +452,26 @@ namespace crypto { public: - GOSTR3410Verifier (GOSTR3410ParamSet paramSet, const uint8_t * signingKey); + GOSTR3410Verifier (GOSTR3410ParamSet paramSet, const uint8_t * signingKey) + { + BIGNUM * x = BN_bin2bn (signingKey, GOSTR3410_PUBLIC_KEY_LENGTH/2, NULL); + BIGNUM * y = BN_bin2bn (signingKey + GOSTR3410_PUBLIC_KEY_LENGTH/2, GOSTR3410_PUBLIC_KEY_LENGTH/2, NULL); + m_PublicKey = GetGOSTR3410Curve (m_ParamSet)->CreatePoint (x, y); + BN_free (x); BN_free (y); + } ~GOSTR3410Verifier () { EC_POINT_free (m_PublicKey); } - bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; + bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const + { + uint8_t digest[32]; + SHA256 (buf, len, digest); // TODO: use GOST 34.11 + BIGNUM * d = BN_bin2bn (digest, 32, nullptr); + BIGNUM * r = BN_bin2bn (signature, GetSignatureLen ()/2, NULL); + BIGNUM * s = BN_bin2bn (signature + GetSignatureLen ()/2, GetSignatureLen ()/2, NULL); + bool ret = GetGOSTR3410Curve (m_ParamSet)->Verify (m_PublicKey, d, r, s); + BN_free (d); BN_free (r); BN_free (s); + return ret; + } size_t GetPublicKeyLen () const { return GOSTR3410_PUBLIC_KEY_LENGTH; } size_t GetSignatureLen () const { return GOSTR3410_SIGNATURE_LENGTH; } @@ -477,7 +493,17 @@ namespace crypto } ~GOSTR3410Signer () { BN_free (m_PrivateKey); } - void Sign (const uint8_t * buf, int len, uint8_t * signature) const; + void Sign (const uint8_t * buf, int len, uint8_t * signature) const + { + uint8_t digest[32]; + SHA256 (buf, len, digest); // TODO: use GOST 34.11 + BIGNUM * d = BN_bin2bn (digest, 32, nullptr); + BIGNUM * r = BN_new (), * s = BN_new (); + GetGOSTR3410Curve (m_ParamSet)->Sign (m_PrivateKey, d, r, s); + bn2buf (r, signature, GOSTR3410_SIGNATURE_LENGTH/2); + bn2buf (s, signature + GOSTR3410_SIGNATURE_LENGTH/2, GOSTR3410_SIGNATURE_LENGTH/2); + BN_free (d); BN_free (r); BN_free (s); + } private: @@ -485,7 +511,20 @@ namespace crypto BIGNUM * m_PrivateKey; }; - void CreateGOSTR3410RandomKeys (GOSTR3410ParamSet paramSet, uint8_t * signingPrivateKey, uint8_t * signingPublicKey); + inline void CreateGOSTR3410RandomKeys (GOSTR3410ParamSet paramSet, uint8_t * signingPrivateKey, uint8_t * signingPublicKey) + { + RAND_bytes (signingPrivateKey, GOSTR3410_PUBLIC_KEY_LENGTH/2); + BIGNUM * priv = BN_bin2bn (signingPrivateKey, GOSTR3410_PUBLIC_KEY_LENGTH/2, nullptr); + const auto& curve = GetGOSTR3410Curve (paramSet); + auto pub = curve->MulP (priv); + BN_free (priv); + BIGNUM * x = BN_new (), * y = BN_new (); + curve->GetXY (pub, x, y); + EC_POINT_free (pub); + bn2buf (x, signingPublicKey, GOSTR3410_PUBLIC_KEY_LENGTH/2); + bn2buf (y, signingPublicKey + GOSTR3410_PUBLIC_KEY_LENGTH/2, GOSTR3410_PUBLIC_KEY_LENGTH/2); + BN_free (x); BN_free (y); + } } }