Botan  2.6.0
Crypto and TLS for C++11
gost_3410.cpp
Go to the documentation of this file.
1 /*
2 * GOST 34.10-2001 implemenation
3 * (C) 2007 Falko Strenzke, FlexSecure GmbH
4 * Manuel Hartl, FlexSecure GmbH
5 * (C) 2008-2010,2015,2018 Jack Lloyd
6 *
7 * Botan is released under the Simplified BSD License (see license.txt)
8 */
9 
10 #include <botan/gost_3410.h>
11 #include <botan/internal/pk_ops_impl.h>
12 #include <botan/reducer.h>
13 #include <botan/der_enc.h>
14 #include <botan/ber_dec.h>
15 
16 namespace Botan {
17 
18 std::vector<uint8_t> GOST_3410_PublicKey::public_key_bits() const
19  {
20  const BigInt x = public_point().get_affine_x();
21  const BigInt y = public_point().get_affine_y();
22 
23  size_t part_size = std::max(x.bytes(), y.bytes());
24 
25  std::vector<uint8_t> bits(2*part_size);
26 
27  x.binary_encode(&bits[part_size - x.bytes()]);
28  y.binary_encode(&bits[2*part_size - y.bytes()]);
29 
30  // Keys are stored in little endian format (WTF)
31  for(size_t i = 0; i != part_size / 2; ++i)
32  {
33  std::swap(bits[i], bits[part_size-1-i]);
34  std::swap(bits[part_size+i], bits[2*part_size-1-i]);
35  }
36 
38  }
39 
41  {
42  std::vector<uint8_t> params =
44  .encode(domain().get_curve_oid())
45  .end_cons()
47 
48  return AlgorithmIdentifier(get_oid(), params);
49  }
50 
52  const std::vector<uint8_t>& key_bits)
53  {
54  OID ecc_param_id;
55 
56  // The parameters also includes hash and cipher OIDs
57  BER_Decoder(alg_id.get_parameters()).start_cons(SEQUENCE).decode(ecc_param_id);
58 
59  m_domain_params = EC_Group(ecc_param_id);
60 
62  BER_Decoder(key_bits).decode(bits, OCTET_STRING);
63 
64  const size_t part_size = bits.size() / 2;
65 
66  // Keys are stored in little endian format (WTF)
67  for(size_t i = 0; i != part_size / 2; ++i)
68  {
69  std::swap(bits[i], bits[part_size-1-i]);
70  std::swap(bits[part_size+i], bits[2*part_size-1-i]);
71  }
72 
73  BigInt x(bits.data(), part_size);
74  BigInt y(&bits[part_size], part_size);
75 
76  m_public_key = domain().point(x, y);
77 
79  "Loaded GOST 34.10 public key is on the curve");
80  }
81 
82 namespace {
83 
84 BigInt decode_le(const uint8_t msg[], size_t msg_len)
85  {
86  secure_vector<uint8_t> msg_le(msg, msg + msg_len);
87 
88  for(size_t i = 0; i != msg_le.size() / 2; ++i)
89  std::swap(msg_le[i], msg_le[msg_le.size()-1-i]);
90 
91  return BigInt(msg_le.data(), msg_le.size());
92  }
93 
94 /**
95 * GOST-34.10 signature operation
96 */
97 class GOST_3410_Signature_Operation final : public PK_Ops::Signature_with_EMSA
98  {
99  public:
100  GOST_3410_Signature_Operation(const GOST_3410_PrivateKey& gost_3410,
101  const std::string& emsa) :
102  PK_Ops::Signature_with_EMSA(emsa),
103  m_group(gost_3410.domain()),
104  m_x(gost_3410.private_value())
105  {}
106 
107  size_t max_input_bits() const override { return m_group.get_order_bits(); }
108 
109  secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len,
110  RandomNumberGenerator& rng) override;
111 
112  private:
113  const EC_Group m_group;
114  const BigInt& m_x;
115  std::vector<BigInt> m_ws;
116  };
117 
118 secure_vector<uint8_t>
119 GOST_3410_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len,
120  RandomNumberGenerator& rng)
121  {
122  const BigInt k = m_group.random_scalar(rng);
123 
124  BigInt e = decode_le(msg, msg_len);
125 
126  e = m_group.mod_order(e);
127  if(e == 0)
128  e = 1;
129 
130  const BigInt r = m_group.mod_order(
131  m_group.blinded_base_point_multiply_x(k, rng, m_ws));
132 
133  const BigInt s = m_group.mod_order(
134  m_group.multiply_mod_order(r, m_x) +
135  m_group.multiply_mod_order(k, e));
136 
137  if(r == 0 || s == 0)
138  throw Internal_Error("GOST 34.10 signature generation failed, r/s equal to zero");
139 
140  return BigInt::encode_fixed_length_int_pair(s, r, m_group.get_order_bytes());
141  }
142 
143 /**
144 * GOST-34.10 verification operation
145 */
146 class GOST_3410_Verification_Operation final : public PK_Ops::Verification_with_EMSA
147  {
148  public:
149 
150  GOST_3410_Verification_Operation(const GOST_3410_PublicKey& gost,
151  const std::string& emsa) :
152  PK_Ops::Verification_with_EMSA(emsa),
153  m_group(gost.domain()),
154  m_public_point(gost.public_point())
155  {}
156 
157  size_t max_input_bits() const override { return m_group.get_order_bits(); }
158 
159  bool with_recovery() const override { return false; }
160 
161  bool verify(const uint8_t msg[], size_t msg_len,
162  const uint8_t sig[], size_t sig_len) override;
163  private:
164  const EC_Group m_group;
165  const PointGFp& m_public_point;
166  };
167 
168 bool GOST_3410_Verification_Operation::verify(const uint8_t msg[], size_t msg_len,
169  const uint8_t sig[], size_t sig_len)
170  {
171  if(sig_len != m_group.get_order_bytes() * 2)
172  return false;
173 
174  const BigInt s(sig, sig_len / 2);
175  const BigInt r(sig + sig_len / 2, sig_len / 2);
176 
177  const BigInt& order = m_group.get_order();
178 
179  if(r <= 0 || r >= order || s <= 0 || s >= order)
180  return false;
181 
182  BigInt e = decode_le(msg, msg_len);
183  e = m_group.mod_order(e);
184  if(e == 0)
185  e = 1;
186 
187  const BigInt v = inverse_mod(e, order);
188 
189  const BigInt z1 = m_group.multiply_mod_order(s, v);
190  const BigInt z2 = m_group.multiply_mod_order(-r, v);
191 
192  const PointGFp R = m_group.point_multiply(z1, m_public_point, z2);
193 
194  if(R.is_zero())
195  return false;
196 
197  return (R.get_affine_x() == r);
198  }
199 
200 }
201 
202 std::unique_ptr<PK_Ops::Verification>
204  const std::string& provider) const
205  {
206  if(provider == "base" || provider.empty())
207  return std::unique_ptr<PK_Ops::Verification>(new GOST_3410_Verification_Operation(*this, params));
208  throw Provider_Not_Found(algo_name(), provider);
209  }
210 
211 std::unique_ptr<PK_Ops::Signature>
213  const std::string& params,
214  const std::string& provider) const
215  {
216  if(provider == "base" || provider.empty())
217  return std::unique_ptr<PK_Ops::Signature>(new GOST_3410_Signature_Operation(*this, params));
218  throw Provider_Not_Found(algo_name(), provider);
219  }
220 
221 }
PointGFp point(const BigInt &x, const BigInt &y) const
Definition: ec_group.cpp:482
std::vector< uint8_t > get_contents_unlocked()
Definition: der_enc.h:27
const PointGFp & public_point() const
Definition: ecc_key.h:57
PointGFp m_public_key
Definition: ecc_key.h:115
BER_Decoder & decode(bool &v)
Definition: ber_dec.cpp:338
void binary_encode(uint8_t buf[]) const
Definition: bigint.cpp:304
DER_Encoder & end_cons()
Definition: der_enc.cpp:146
BigInt get_affine_x() const
Definition: point_gfp.cpp:491
std::unique_ptr< PK_Ops::Signature > create_signature_op(RandomNumberGenerator &rng, const std::string &params, const std::string &provider) const override
Definition: gost_3410.cpp:212
BigInt get_affine_y() const
Definition: point_gfp.cpp:510
#define BOTAN_ASSERT(expr, assertion_made)
Definition: assert.h:30
std::vector< uint8_t > public_key_bits() const override
Definition: gost_3410.cpp:18
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:202
virtual OID get_oid() const
Definition: pk_keys.cpp:51
const EC_Group & domain() const
Definition: ecc_key.h:72
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition: numthry.cpp:279
Definition: alg_id.cpp:13
size_t bytes() const
Definition: bigint.cpp:208
const std::vector< uint8_t > & get_parameters() const
Definition: alg_id.h:38
bool on_the_curve() const
Definition: point_gfp.cpp:530
std::string algo_name() const override
Definition: gost_3410.h:45
AlgorithmIdentifier algorithm_identifier() const override
Definition: gost_3410.cpp:40
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:136
std::unique_ptr< PK_Ops::Verification > create_verification_op(const std::string &params, const std::string &provider) const override
Definition: gost_3410.cpp:203
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
static secure_vector< uint8_t > encode_fixed_length_int_pair(const BigInt &n1, const BigInt &n2, size_t bytes)
Definition: big_code.cpp:103
EC_Group m_domain_params
Definition: ecc_key.h:114