Botan  1.10.9
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 Jack Lloyd
6 *
7 * Distributed under the terms of the Botan license
8 */
9 
10 #include <botan/gost_3410.h>
11 #include <botan/der_enc.h>
12 #include <botan/ber_dec.h>
13 #include <botan/internal/assert.h>
14 
15 namespace Botan {
16 
18  {
19  // Trust CryptoPro to come up with something obnoxious
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  MemoryVector<byte> 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 
37  return DER_Encoder().encode(bits, OCTET_STRING).get_contents();
38  }
39 
41  {
42  MemoryVector<byte> params =
44  .encode(OID(domain().get_oid()))
45  .end_cons()
46  .get_contents();
47 
48  return AlgorithmIdentifier(get_oid(), params);
49  }
50 
52  const MemoryRegion<byte>& key_bits)
53  {
54  OID ecc_param_id;
55 
56  // Also includes hash and cipher OIDs... brilliant design guys
57  BER_Decoder(alg_id.parameters).start_cons(SEQUENCE).decode(ecc_param_id);
58 
59  domain_params = EC_Group(ecc_param_id);
60 
61  SecureVector<byte> bits;
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[0], part_size);
74  BigInt y(&bits[part_size], part_size);
75 
76  public_key = PointGFp(domain().get_curve(), x, y);
77 
79  "Loaded GOST 34.10 public key not on the curve");
80  }
81 
82 namespace {
83 
84 BigInt decode_le(const byte msg[], size_t msg_len)
85  {
86  SecureVector<byte> msg_le(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[0], msg_le.size());
92  }
93 
94 }
95 
97  const GOST_3410_PrivateKey& gost_3410) :
98 
99  base_point(gost_3410.domain().get_base_point()),
100  order(gost_3410.domain().get_order()),
101  x(gost_3410.private_value())
102  {
103  }
104 
106 GOST_3410_Signature_Operation::sign(const byte msg[], size_t msg_len,
108  {
109  BigInt k;
110  do
111  k.randomize(rng, order.bits()-1);
112  while(k >= order);
113 
114  BigInt e = decode_le(msg, msg_len);
115 
116  e %= order;
117  if(e == 0)
118  e = 1;
119 
120  PointGFp k_times_P = base_point * k;
121 
122  BOTAN_ASSERT(k_times_P.on_the_curve(),
123  "GOST 34.10 k*g not on the curve");
124 
125  BigInt r = k_times_P.get_affine_x() % order;
126 
127  BigInt s = (r*x + k*e) % order;
128 
129  if(r == 0 || s == 0)
130  throw Invalid_State("GOST 34.10: r == 0 || s == 0");
131 
132  SecureVector<byte> output(2*order.bytes());
133  s.binary_encode(&output[output.size() / 2 - s.bytes()]);
134  r.binary_encode(&output[output.size() - r.bytes()]);
135  return output;
136  }
137 
139  base_point(gost.domain().get_base_point()),
140  public_point(gost.public_point()),
141  order(gost.domain().get_order())
142  {
143  }
144 
145 bool GOST_3410_Verification_Operation::verify(const byte msg[], size_t msg_len,
146  const byte sig[], size_t sig_len)
147  {
148  if(sig_len != order.bytes()*2)
149  return false;
150 
151  BigInt e = decode_le(msg, msg_len);
152 
153  BigInt s(sig, sig_len / 2);
154  BigInt r(sig + sig_len / 2, sig_len / 2);
155 
156  if(r <= 0 || r >= order || s <= 0 || s >= order)
157  return false;
158 
159  e %= order;
160  if(e == 0)
161  e = 1;
162 
163  BigInt v = inverse_mod(e, order);
164 
165  BigInt z1 = (s*v) % order;
166  BigInt z2 = (-r*v) % order;
167 
168  PointGFp R = multi_exponentiate(base_point, z1,
169  public_point, z2);
170 
171  if(R.is_zero())
172  return false;
173 
174  return (R.get_affine_x() == r);
175  }
176 
177 }
void binary_encode(byte buf[]) const
Definition: bigint.cpp:340
SecureVector< byte > get_contents()
Definition: der_enc.cpp:122
BigInt get_affine_y() const
Definition: point_gfp.cpp:406
const EC_Group & domain() const
Definition: ecc_key.h:60
BER_Decoder & decode(bool &)
Definition: ber_dec.cpp:338
SecureVector< byte > sign(const byte msg[], size_t msg_len, RandomNumberGenerator &rng)
Definition: gost_3410.cpp:106
PointGFp public_key
Definition: ecc_key.h:85
GOST_3410_Verification_Operation(const GOST_3410_PublicKey &gost)
Definition: gost_3410.cpp:138
AlgorithmIdentifier algorithm_identifier() const
Definition: gost_3410.cpp:40
SecureVector< byte > parameters
Definition: alg_id.h:36
DER_Encoder & end_cons()
Definition: der_enc.cpp:145
BER_Decoder start_cons(ASN1_Tag, ASN1_Tag=UNIVERSAL)
Definition: ber_dec.cpp:232
#define BOTAN_ASSERT(expr, msg)
Definition: assert.h:19
virtual OID get_oid() const
Definition: pk_keys.cpp:17
const PointGFp & public_point() const
Definition: ecc_key.h:45
unsigned char byte
Definition: types.h:22
BigInt get_affine_x() const
Definition: point_gfp.cpp:392
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:209
size_t bits() const
Definition: bigint.cpp:253
RandomNumberGenerator * rng
Definition: global_rng.cpp:165
void randomize(RandomNumberGenerator &rng, size_t bitsize=0)
Definition: big_rand.cpp:29
size_t size() const
Definition: secmem.h:29
MemoryVector< byte > x509_subject_public_key() const
Definition: gost_3410.cpp:17
bool verify(const byte msg[], size_t msg_len, const byte sig[], size_t sig_len)
Definition: gost_3410.cpp:145
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition: numthry.cpp:202
bool on_the_curve() const
Definition: point_gfp.cpp:419
BigInt r
Definition: numthry.cpp:26
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:135
bool is_zero() const
Definition: point_gfp.h:146
void swap(Botan::MemoryRegion< T > &x, Botan::MemoryRegion< T > &y)
Definition: secmem.h:425
GOST_3410_Signature_Operation(const GOST_3410_PrivateKey &gost_3410)
Definition: gost_3410.cpp:96
PointGFp multi_exponentiate(const PointGFp &p1, const BigInt &z1, const PointGFp &p2, const BigInt &z2)
Definition: point_gfp.cpp:257
size_t s
Definition: numthry.cpp:27
EC_Group domain_params
Definition: ecc_key.h:84
size_t bytes() const
Definition: bigint.cpp:245