10#include <botan/gost_3410.h>
11#include <botan/internal/pk_ops_impl.h>
12#include <botan/internal/point_mul.h>
13#include <botan/reducer.h>
14#include <botan/der_enc.h>
15#include <botan/ber_dec.h>
24 size_t part_size = std::max(x.
bytes(), y.
bytes());
26 std::vector<uint8_t> bits(2*part_size);
32 for(
size_t i = 0; i != part_size / 2; ++i)
34 std::swap(bits[i], bits[part_size-1-i]);
35 std::swap(bits[part_size+i], bits[2*part_size-1-i]);
38 std::vector<uint8_t> output;
47 if(p_bits == 256 || p_bits == 512)
50 throw Encoding_Error(
"GOST-34.10-2012 is not defined for parameters of this size");
55 std::vector<uint8_t> params;
66 const std::vector<uint8_t>& key_bits)
76 if(p_bits != 256 && p_bits != 512)
77 throw Decoding_Error(
"GOST-34.10-2012 is not defined for parameters of size " +
83 if(bits.size() != 2*(p_bits/8))
84 throw Decoding_Error(
"GOST-34.10-2020 invalid encoding of public key");
86 const size_t part_size = bits.size() / 2;
89 for(
size_t i = 0; i != part_size / 2; ++i)
91 std::swap(bits[i], bits[part_size-1-i]);
92 std::swap(bits[part_size+i], bits[2*part_size-1-i]);
95 BigInt x(bits.data(), part_size);
96 BigInt y(&bits[part_size], part_size);
101 "Loaded GOST 34.10 public key is on the curve");
110 if(p_bits != 256 && p_bits != 512)
111 throw Decoding_Error(
"GOST-34.10-2012 is not defined for parameters of size " +
122BigInt decode_le(
const uint8_t msg[],
size_t msg_len)
126 for(
size_t i = 0; i != msg_le.size() / 2; ++i)
127 std::swap(msg_le[i], msg_le[msg_le.size()-1-i]);
129 return BigInt(msg_le.data(), msg_le.size());
135class GOST_3410_Signature_Operation
final :
public PK_Ops::Signature_with_EMSA
138 GOST_3410_Signature_Operation(
const GOST_3410_PrivateKey& gost_3410,
139 const std::string& emsa) :
140 PK_Ops::Signature_with_EMSA(emsa),
141 m_group(gost_3410.domain()),
142 m_x(gost_3410.private_value())
145 size_t signature_length()
const override {
return 2*m_group.get_order_bytes(); }
147 size_t max_input_bits()
const override {
return m_group.get_order_bits(); }
149 secure_vector<uint8_t> raw_sign(
const uint8_t msg[],
size_t msg_len,
150 RandomNumberGenerator& rng)
override;
153 const EC_Group m_group;
155 std::vector<BigInt> m_ws;
158secure_vector<uint8_t>
159GOST_3410_Signature_Operation::raw_sign(
const uint8_t msg[],
size_t msg_len,
160 RandomNumberGenerator& rng)
162 const BigInt k = m_group.random_scalar(rng);
164 BigInt e = decode_le(msg, msg_len);
166 e = m_group.mod_order(e);
170 const BigInt r = m_group.mod_order(
171 m_group.blinded_base_point_multiply_x(k, rng, m_ws));
173 const BigInt s = m_group.mod_order(
174 m_group.multiply_mod_order(r, m_x) +
175 m_group.multiply_mod_order(k, e));
178 throw Internal_Error(
"GOST 34.10 signature generation failed, r/s equal to zero");
186class GOST_3410_Verification_Operation
final :
public PK_Ops::Verification_with_EMSA
190 GOST_3410_Verification_Operation(
const GOST_3410_PublicKey& gost,
191 const std::string& emsa) :
192 PK_Ops::Verification_with_EMSA(emsa),
193 m_group(gost.domain()),
194 m_gy_mul(m_group.get_base_point(), gost.public_point())
197 size_t max_input_bits()
const override {
return m_group.get_order_bits(); }
199 bool with_recovery()
const override {
return false; }
201 bool verify(
const uint8_t msg[],
size_t msg_len,
202 const uint8_t sig[],
size_t sig_len)
override;
204 const EC_Group m_group;
205 const PointGFp_Multi_Point_Precompute m_gy_mul;
208bool GOST_3410_Verification_Operation::verify(
const uint8_t msg[],
size_t msg_len,
209 const uint8_t sig[],
size_t sig_len)
211 if(sig_len != m_group.get_order_bytes() * 2)
214 const BigInt s(sig, sig_len / 2);
215 const BigInt r(sig + sig_len / 2, sig_len / 2);
217 const BigInt& order = m_group.get_order();
219 if(r <= 0 || r >= order || s <= 0 || s >= order)
222 BigInt e = decode_le(msg, msg_len);
223 e = m_group.mod_order(e);
227 const BigInt
v = m_group.inverse_mod_order(e);
229 const BigInt z1 = m_group.multiply_mod_order(s,
v);
230 const BigInt z2 = m_group.multiply_mod_order(-r,
v);
232 const PointGFp R = m_gy_mul.
multi_exp(z1, z2);
237 return (R.get_affine_x() == r);
242std::unique_ptr<PK_Ops::Verification>
244 const std::string& provider)
const
246 if(provider ==
"base" || provider.empty())
247 return std::make_unique<GOST_3410_Verification_Operation>(*
this, params);
251std::unique_ptr<PK_Ops::Signature>
253 const std::string& params,
254 const std::string& provider)
const
256 if(provider ==
"base" || provider.empty())
257 return std::make_unique<GOST_3410_Signature_Operation>(*
this, params);
#define BOTAN_ASSERT(expr, assertion_made)
const std::vector< uint8_t > & get_parameters() const
BER_Decoder & decode(bool &out)
BER_Decoder start_sequence()
void binary_encode(uint8_t buf[]) const
static secure_vector< uint8_t > encode_fixed_length_int_pair(const BigInt &n1, const BigInt &n2, size_t bytes)
DER_Encoder & start_sequence()
DER_Encoder & encode(bool b)
PointGFp point(const BigInt &x, const BigInt &y) const
size_t get_p_bits() const
const OID & get_curve_oid() const
const EC_Group & domain() const
const PointGFp & public_point() const
std::unique_ptr< Public_Key > public_key() const override
GOST_3410_PrivateKey(const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &key_bits)
std::unique_ptr< PK_Ops::Signature > create_signature_op(RandomNumberGenerator &rng, const std::string ¶ms, const std::string &provider) const override
AlgorithmIdentifier algorithm_identifier() const override
GOST_3410_PublicKey()=default
std::string algo_name() const override
std::vector< uint8_t > public_key_bits() const override
std::unique_ptr< PK_Ops::Verification > create_verification_op(const std::string ¶ms, const std::string &provider) const override
PointGFp multi_exp(const BigInt &k1, const BigInt &k2) const
bool on_the_curve() const
BigInt get_affine_y() const
BigInt get_affine_x() const
virtual OID get_oid() const
int(* final)(unsigned char *, CTX *)
std::string to_string(const BER_Object &obj)
std::vector< T, secure_allocator< T > > secure_vector