aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/gost_3410/gost_3410.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pubkey/gost_3410/gost_3410.cpp')
-rw-r--r--src/lib/pubkey/gost_3410/gost_3410.cpp68
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())