From ba89c60b6deaa2eb5a64cd5051919e1b0997b8b3 Mon Sep 17 00:00:00 2001 From: orignal Date: Fri, 10 Mar 2017 11:55:30 -0500 Subject: [PATCH] correct param set for GOST R 34.10 verification --- Identity.cpp | 6 +++--- Signature.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++++-- Signature.h | 28 +++++--------------------- 3 files changed, 62 insertions(+), 28 deletions(-) diff --git a/Identity.cpp b/Identity.cpp index f76bc62b..fb45764d 100644 --- a/Identity.cpp +++ b/Identity.cpp @@ -97,14 +97,14 @@ namespace data } case SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: { - size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32 + size_t padding = 128 - i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH; // 96 = 128 - 32 RAND_bytes (m_StandardIdentity.signingKey, padding); memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::EDDSA25519_PUBLIC_KEY_LENGTH); break; } case SIGNING_KEY_TYPE_GOSTR3410_A_GOSTR3411: { - size_t padding = 128 - i2p::crypto::GOSTR3410_PUBLIC_KEY_LENGTH; // 64 = 128 - 64 + size_t padding = 128 - i2p::crypto::GOSTR3410_PUBLIC_KEY_LENGTH; // 64 = 128 - 64 RAND_bytes (m_StandardIdentity.signingKey, padding); memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::GOSTR3410_PUBLIC_KEY_LENGTH); break; @@ -380,7 +380,7 @@ 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 (m_StandardIdentity.signingKey + padding)); + UpdateVerifier (new i2p::crypto::GOSTR3410Verifier (i2p::crypto::eGOSTR3410CryptoProA, m_StandardIdentity.signingKey + padding)); break; } default: diff --git a/Signature.cpp b/Signature.cpp index 30e4fc03..15d606dc 100644 --- a/Signature.cpp +++ b/Signature.cpp @@ -532,6 +532,13 @@ namespace crypto return EC_POINT_get_affine_coordinates_GFp (m_Group, p, x, y, nullptr); } + EC_POINT * CreatePoint (const BIGNUM * x, const BIGNUM * y) const + { + EC_POINT * p = EC_POINT_new (m_Group); + EC_POINT_set_affine_coordinates_GFp (m_Group, p, x, y, nullptr); + return p; + } + void Sign (const BIGNUM * priv, const BIGNUM * digest, BIGNUM * r, BIGNUM * s) { BN_CTX * ctx = BN_CTX_new (); @@ -551,6 +558,31 @@ namespace crypto BN_CTX_free (ctx); } + bool Verify (const EC_POINT * pub, const BIGNUM * digest, const BIGNUM * r, const BIGNUM * s) + { + BN_CTX * ctx = BN_CTX_new (); + BN_CTX_start (ctx); + BIGNUM * q = BN_CTX_get (ctx); + EC_GROUP_get_order(m_Group, q, ctx); + BIGNUM * h = BN_CTX_get (ctx); + BN_mod (h, digest, q, ctx); // h = digest % q + BN_mod_inverse (h, h, q, ctx); // 1/h mod q + BIGNUM * z1 = BN_CTX_get (ctx); + BN_mod_mul (z1, s, h, q, ctx); // z1 = s/h + BIGNUM * z2 = BN_CTX_get (ctx); + BN_sub (z2, q, r); // z2 = -r + BN_mod_mul (z2, z2, h, q, ctx); // z2 = -r/h + EC_POINT * C = EC_POINT_new (m_Group); + EC_POINT_mul (m_Group, C, z1, pub, z2, ctx); // z1*P + z2*pub + BIGNUM * x = BN_CTX_get (ctx); + GetXY (C, x, nullptr); // Cx + BN_mod (x, x, q, ctx); // Cx % q + bool ret = !BN_cmp (x, r); // Cx = r ? + EC_POINT_free (C); + BN_CTX_end (ctx); + BN_CTX_free (ctx); + return ret; + } private: @@ -614,14 +646,34 @@ namespace crypto return g_GOSTR3410Curves[paramSet]; } + 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 (); - const auto& curve = GetGOSTR3410Curve (m_ParamSet); - curve->Sign (m_PrivateKey, d, r, s); + 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); diff --git a/Signature.h b/Signature.h index c505524c..0ccb99ea 100644 --- a/Signature.h +++ b/Signature.h @@ -462,36 +462,18 @@ namespace crypto { public: - GOSTR3410Verifier (const uint8_t * signingKey) - { - m_PublicKey = EVP_PKEY_new (); - EC_KEY * ecKey = EC_KEY_new (); - EVP_PKEY_assign (m_PublicKey, NID_id_GostR3410_2001, ecKey); - EVP_PKEY_copy_parameters (m_PublicKey, GetGostPKEY ()); - 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); - EC_KEY_set_public_key_affine_coordinates (ecKey, x, y); - BN_free (x); BN_free (y); - } - ~GOSTR3410Verifier () { EVP_PKEY_free (m_PublicKey); } + GOSTR3410Verifier (GOSTR3410ParamSet paramSet, const uint8_t * signingKey); + ~GOSTR3410Verifier () { EC_POINT_free (m_PublicKey); } - bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const - { - uint8_t digest[32]; - GOSTR3411 (buf, len, digest); - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new (m_PublicKey, nullptr); - EVP_PKEY_verify_init (ctx); - int ret = EVP_PKEY_verify (ctx, signature, GOSTR3410_SIGNATURE_LENGTH, digest, 32); - EVP_PKEY_CTX_free (ctx); - return ret == 1; - } + bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; size_t GetPublicKeyLen () const { return GOSTR3410_PUBLIC_KEY_LENGTH; } size_t GetSignatureLen () const { return GOSTR3410_SIGNATURE_LENGTH; } private: - EVP_PKEY * m_PublicKey; + GOSTR3410ParamSet m_ParamSet; + EC_POINT * m_PublicKey; }; class GOSTR3410Signer: public Signer