From e87724703268edee2d6095c9db65a725defe7966 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 14 Mar 2017 16:41:06 -0400 Subject: [PATCH] support of GOST 34.10-2012 512 bits --- Gost.cpp | 1 + Gost.h | 2 ++ Identity.cpp | 12 +++++------ Signature.h | 58 +++++++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 57 insertions(+), 16 deletions(-) diff --git a/Gost.cpp b/Gost.cpp index 63625baa..6c5d7f24 100644 --- a/Gost.cpp +++ b/Gost.cpp @@ -12,6 +12,7 @@ namespace crypto GOSTR3410Curve::GOSTR3410Curve (BIGNUM * a, BIGNUM * b, BIGNUM * p, BIGNUM * q, BIGNUM * x, BIGNUM * y) { + m_KeyLen = BN_num_bytes (p); BN_CTX * ctx = BN_CTX_new (); m_Group = EC_GROUP_new_curve_GFp (p, a, b, ctx); EC_POINT * P = EC_POINT_new (m_Group); diff --git a/Gost.h b/Gost.h index 62a8aea1..d0f63ed7 100644 --- a/Gost.h +++ b/Gost.h @@ -33,6 +33,7 @@ namespace crypto GOSTR3410Curve (BIGNUM * a, BIGNUM * b, BIGNUM * p, BIGNUM * q, BIGNUM * x, BIGNUM * y); ~GOSTR3410Curve (); + size_t GetKeyLen () const { return m_KeyLen; }; EC_POINT * MulP (const BIGNUM * n) const; bool GetXY (const EC_POINT * p, BIGNUM * x, BIGNUM * y) const; EC_POINT * CreatePoint (const BIGNUM * x, const BIGNUM * y) const; @@ -42,6 +43,7 @@ namespace crypto private: EC_GROUP * m_Group; + size_t m_KeyLen; // in bytes }; std::unique_ptr& GetGOSTR3410Curve (GOSTR3410ParamSet paramSet); diff --git a/Identity.cpp b/Identity.cpp index e6bf34bf..89eb43f6 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -382,19 +382,19 @@ namespace data case SIGNING_KEY_TYPE_GOSTR3410_A_GOSTR3411: { size_t padding = 128 - i2p::crypto::GOSTR3410_PUBLIC_KEY_LENGTH; // 64 = 128 - 64 - UpdateVerifier (new i2p::crypto::GOSTR3410Verifier (i2p::crypto::eGOSTR3410CryptoProA, m_StandardIdentity.signingKey + padding)); + UpdateVerifier (new i2p::crypto::GOSTR3410_2001_Verifier (i2p::crypto::eGOSTR3410CryptoProA, m_StandardIdentity.signingKey + padding)); break; } case SIGNING_KEY_TYPE_GOSTR3410_B_GOSTR3411: { size_t padding = 128 - i2p::crypto::GOSTR3410_PUBLIC_KEY_LENGTH; // 64 = 128 - 64 - UpdateVerifier (new i2p::crypto::GOSTR3410Verifier (i2p::crypto::eGOSTR3410CryptoProB, m_StandardIdentity.signingKey + padding)); + UpdateVerifier (new i2p::crypto::GOSTR3410_2001_Verifier (i2p::crypto::eGOSTR3410CryptoProB, m_StandardIdentity.signingKey + padding)); break; } case SIGNING_KEY_TYPE_GOSTR3410_C_GOSTR3411: { size_t padding = 128 - i2p::crypto::GOSTR3410_PUBLIC_KEY_LENGTH; // 64 = 128 - 64 - UpdateVerifier (new i2p::crypto::GOSTR3410Verifier (i2p::crypto::eGOSTR3410CryptoProC, m_StandardIdentity.signingKey + padding)); + UpdateVerifier (new i2p::crypto::GOSTR3410_2001_Verifier (i2p::crypto::eGOSTR3410CryptoProC, m_StandardIdentity.signingKey + padding)); break; } default: @@ -539,13 +539,13 @@ namespace data m_Signer.reset (new i2p::crypto::EDDSA25519Signer (m_SigningPrivateKey, m_Public->GetStandardIdentity ().certificate - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH)); break; case SIGNING_KEY_TYPE_GOSTR3410_A_GOSTR3411: - m_Signer.reset (new i2p::crypto::GOSTR3410Signer (i2p::crypto::eGOSTR3410CryptoProA, m_SigningPrivateKey)); + m_Signer.reset (new i2p::crypto::GOSTR3410_2001_Signer (i2p::crypto::eGOSTR3410CryptoProA, m_SigningPrivateKey)); break; case SIGNING_KEY_TYPE_GOSTR3410_B_GOSTR3411: - m_Signer.reset (new i2p::crypto::GOSTR3410Signer (i2p::crypto::eGOSTR3410CryptoProB, m_SigningPrivateKey)); + m_Signer.reset (new i2p::crypto::GOSTR3410_2001_Signer (i2p::crypto::eGOSTR3410CryptoProB, m_SigningPrivateKey)); break; case SIGNING_KEY_TYPE_GOSTR3410_C_GOSTR3411: - m_Signer.reset (new i2p::crypto::GOSTR3410Signer (i2p::crypto::eGOSTR3410CryptoProC, m_SigningPrivateKey)); + m_Signer.reset (new i2p::crypto::GOSTR3410_2001_Signer (i2p::crypto::eGOSTR3410CryptoProC, m_SigningPrivateKey)); break; default: LogPrint (eLogError, "Identity: Signing key type ", (int)m_Public->GetSigningKeyType (), " is not supported"); diff --git a/Signature.h b/Signature.h index 62a36cd3..c76d15a3 100644 --- a/Signature.h +++ b/Signature.h @@ -443,11 +443,43 @@ namespace crypto memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH); } - // ГОСТ Р 34.10-2001 - + + // ГОСТ Р 34.11 + struct GOSTR3411_2001_Hash + { + static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest) + { + SHA256 (buf, len, digest); // TODO: implement GOST R 34.11 - 2001 + } + + enum { hashLen = 32 }; + }; + + struct GOSTR3411_2012_256_Hash + { + static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest) + { + SHA256 (buf, len, digest); // TODO: implement GOST R 34.11 - 2012 + } + + enum { hashLen = 32 }; + }; + + struct GOSTR3411_2012_512_Hash + { + static void CalculateHash (const uint8_t * buf, size_t len, uint8_t * digest) + { + SHA512 (buf, len, digest); // TODO: implement GOST R 34.11 - 2012 + } + + enum { hashLen = 32 }; + }; + + // ГОСТ Р 34.10 const size_t GOSTR3410_PUBLIC_KEY_LENGTH = 64; const size_t GOSTR3410_SIGNATURE_LENGTH = 64; + template class GOSTR3410Verifier: public Verifier { public: @@ -463,8 +495,8 @@ namespace crypto 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 + uint8_t digest[Hash::hashLen]; + Hash::CalculateHash (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); @@ -482,6 +514,7 @@ namespace crypto EC_POINT * m_PublicKey; }; + template class GOSTR3410Signer: public Signer { public: @@ -495,8 +528,8 @@ namespace crypto 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 + uint8_t digest[Hash::hashLen]; + Hash::CalculateHash (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); @@ -513,18 +546,23 @@ namespace crypto 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 keyLen = curve->GetKeyLen (); + RAND_bytes (signingPrivateKey, keyLen); + BIGNUM * priv = BN_bin2bn (signingPrivateKey, keyLen, nullptr); + 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); + bn2buf (x, signingPublicKey, keyLen); + bn2buf (y, signingPublicKey + keyLen, keyLen); BN_free (x); BN_free (y); } + + typedef GOSTR3410Verifier GOSTR3410_2001_Verifier; + typedef GOSTR3410Signer GOSTR3410_2001_Signer; } }