diff options
Diffstat (limited to 'src/lib/pubkey/gost_3410/gost_3410.cpp')
-rw-r--r-- | src/lib/pubkey/gost_3410/gost_3410.cpp | 68 |
1 files changed, 33 insertions, 35 deletions
diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp index f005a349b..5d7c425d0 100644 --- a/src/lib/pubkey/gost_3410/gost_3410.cpp +++ b/src/lib/pubkey/gost_3410/gost_3410.cpp @@ -2,7 +2,7 @@ * GOST 34.10-2001 implemenation * (C) 2007 Falko Strenzke, FlexSecure GmbH * Manuel Hartl, FlexSecure GmbH -* (C) 2008-2010,2015 Jack Lloyd +* (C) 2008-2010,2015,2018 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -100,19 +100,18 @@ class GOST_3410_Signature_Operation final : public PK_Ops::Signature_with_EMSA GOST_3410_Signature_Operation(const GOST_3410_PrivateKey& gost_3410, const std::string& emsa) : PK_Ops::Signature_with_EMSA(emsa), - m_order(gost_3410.domain().get_order()), - m_mod_order(m_order), - m_base_point(gost_3410.domain().get_base_point(), m_order), - m_x(gost_3410.private_value()) {} + m_group(gost_3410.domain()), + m_base_point(m_group.get_base_point(), m_group.get_order()), + m_x(gost_3410.private_value()) + {} - size_t max_input_bits() const override { return m_order.bits(); } + size_t max_input_bits() const override { return m_group.get_order_bits(); } secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len, - RandomNumberGenerator& rng) override; + RandomNumberGenerator& rng) override; private: - const BigInt& m_order; - Modular_Reducer m_mod_order; + const EC_Group m_group; Blinded_Point_Multiply m_base_point; const BigInt& m_x; }; @@ -122,29 +121,28 @@ GOST_3410_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len, RandomNumberGenerator& rng) { BigInt k; + do - k.randomize(rng, m_order.bits()-1); - while(k >= m_order); + { + k.randomize(rng, m_group.get_order_bits() - 1); + } while(k >= m_group.get_order()); BigInt e = decode_le(msg, msg_len); - e = m_mod_order.reduce(e); + e = m_group.mod_order(e); if(e == 0) e = 1; const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng); BOTAN_ASSERT(k_times_P.on_the_curve(), "GOST 34.10 k*g is on the curve"); - const BigInt r = m_mod_order.reduce(k_times_P.get_affine_x()); - const BigInt s = m_mod_order.reduce(r*m_x + k*e); + const BigInt r = m_group.mod_order(k_times_P.get_affine_x()); + const BigInt s = m_group.mod_order(r*m_x + k*e); if(r == 0 || s == 0) - throw Invalid_State("GOST 34.10: r == 0 || s == 0"); + throw Internal_Error("GOST 34.10 signature generation failed, r/s equal to zero"); - secure_vector<uint8_t> output(2*m_order.bytes()); - s.binary_encode(&output[output.size() / 2 - s.bytes()]); - r.binary_encode(&output[output.size() - r.bytes()]); - return output; + return BigInt::encode_fixed_length_int_pair(s, r, m_group.get_order_bytes()); } /** @@ -157,46 +155,46 @@ class GOST_3410_Verification_Operation final : public PK_Ops::Verification_with_ GOST_3410_Verification_Operation(const GOST_3410_PublicKey& gost, const std::string& emsa) : PK_Ops::Verification_with_EMSA(emsa), - m_base_point(gost.domain().get_base_point()), - m_public_point(gost.public_point()), - m_order(gost.domain().get_order()) {} + m_group(gost.domain()), + m_public_point(gost.public_point()) + {} - size_t max_input_bits() const override { return m_order.bits(); } + size_t max_input_bits() const override { return m_group.get_order_bits(); } bool with_recovery() const override { return false; } bool verify(const uint8_t msg[], size_t msg_len, const uint8_t sig[], size_t sig_len) override; private: - const PointGFp& m_base_point; + const EC_Group m_group; const PointGFp& m_public_point; - const BigInt& m_order; }; bool GOST_3410_Verification_Operation::verify(const uint8_t msg[], size_t msg_len, const uint8_t sig[], size_t sig_len) { - if(sig_len != m_order.bytes()*2) + if(sig_len != m_group.get_order_bytes() * 2) return false; - BigInt e = decode_le(msg, msg_len); + const BigInt s(sig, sig_len / 2); + const BigInt r(sig + sig_len / 2, sig_len / 2); - BigInt s(sig, sig_len / 2); - BigInt r(sig + sig_len / 2, sig_len / 2); + const BigInt& order = m_group.get_order(); - if(r <= 0 || r >= m_order || s <= 0 || s >= m_order) + if(r <= 0 || r >= order || s <= 0 || s >= order) return false; - e %= m_order; + BigInt e = decode_le(msg, msg_len); + e = m_group.mod_order(e); if(e == 0) e = 1; - BigInt v = inverse_mod(e, m_order); + const BigInt v = inverse_mod(e, order); - BigInt z1 = (s*v) % m_order; - BigInt z2 = (-r*v) % m_order; + const BigInt z1 = m_group.multiply_mod_order(s, v); + const BigInt z2 = m_group.multiply_mod_order(-r, v); - PointGFp R = multi_exponentiate(m_base_point, z1, + PointGFp R = multi_exponentiate(m_group.get_base_point(), z1, m_public_point, z2); if(R.is_zero()) |