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>
25 std::vector<uint8_t> bits(2*part_size);
31 for(
size_t i = 0; i != part_size / 2; ++i)
33 std::swap(bits[i], bits[part_size-1-i]);
34 std::swap(bits[part_size+i], bits[2*part_size-1-i]);
42 std::vector<uint8_t> params =
52 const std::vector<uint8_t>& key_bits)
64 const size_t part_size = bits.size() / 2;
67 for(
size_t i = 0; i != part_size / 2; ++i)
69 std::swap(bits[i], bits[part_size-1-i]);
70 std::swap(bits[part_size+i], bits[2*part_size-1-i]);
73 BigInt x(bits.data(), part_size);
74 BigInt y(&bits[part_size], part_size);
79 "Loaded GOST 34.10 public key is on the curve");
84 BigInt decode_le(
const uint8_t msg[],
size_t msg_len)
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]);
91 return BigInt(msg_le.data(), msg_le.size());
97 class GOST_3410_Signature_Operation :
public PK_Ops::Signature_with_EMSA
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_order(gost_3410.domain().get_order()),
106 m_x(gost_3410.private_value()) {}
108 size_t max_input_bits()
const override {
return m_order.bits(); }
110 secure_vector<uint8_t> raw_sign(
const uint8_t msg[],
size_t msg_len,
111 RandomNumberGenerator& rng)
override;
120 secure_vector<uint8_t>
121 GOST_3410_Signature_Operation::raw_sign(
const uint8_t msg[],
size_t msg_len,
122 RandomNumberGenerator& rng)
129 BigInt e = decode_le(msg, msg_len);
136 BOTAN_ASSERT(k_times_P.on_the_curve(),
"GOST 34.10 k*g is on the curve");
142 throw Invalid_State(
"GOST 34.10: r == 0 || s == 0");
145 s.binary_encode(&output[output.size() / 2 - s.bytes()]);
146 r.binary_encode(&output[output.size() - r.bytes()]);
153 class GOST_3410_Verification_Operation :
public PK_Ops::Verification_with_EMSA
157 GOST_3410_Verification_Operation(
const GOST_3410_PublicKey& gost,
158 const std::string& emsa) :
159 PK_Ops::Verification_with_EMSA(emsa),
162 m_order(gost.domain().get_order()) {}
164 size_t max_input_bits()
const override {
return m_order.bits(); }
166 bool with_recovery()
const override {
return false; }
168 bool verify(
const uint8_t msg[],
size_t msg_len,
169 const uint8_t sig[],
size_t sig_len)
override;
176 bool GOST_3410_Verification_Operation::verify(
const uint8_t msg[],
size_t msg_len,
177 const uint8_t sig[],
size_t sig_len)
182 BigInt e = decode_le(msg, msg_len);
184 BigInt s(sig, sig_len / 2);
185 BigInt r(sig + sig_len / 2, sig_len / 2);
205 return (R.get_affine_x() == r);
210 std::unique_ptr<PK_Ops::Verification>
212 const std::string& provider)
const
214 if(provider ==
"base" || provider.empty())
215 return std::unique_ptr<PK_Ops::Verification>(
new GOST_3410_Verification_Operation(*
this, params));
219 std::unique_ptr<PK_Ops::Signature>
221 const std::string& params,
222 const std::string& provider)
const
224 if(provider ==
"base" || provider.empty())
225 return std::unique_ptr<PK_Ops::Signature>(
new GOST_3410_Signature_Operation(*
this, params));
void binary_encode(uint8_t buf[]) const
BigInt get_affine_y() const
std::vector< uint8_t > get_contents_unlocked()
const EC_Group & domain() const
std::vector< uint8_t > parameters
BER_Decoder & decode(bool &v)
std::unique_ptr< PK_Ops::Signature > create_signature_op(RandomNumberGenerator &rng, const std::string ¶ms, const std::string &provider) const override
virtual OID get_oid() const
const PointGFp & public_point() const
#define BOTAN_ASSERT(expr, assertion_made)
BigInt get_affine_x() const
std::vector< uint8_t > public_key_bits() const override
DER_Encoder & encode(bool b)
const PointGFp & m_public_point
std::vector< T, secure_allocator< T >> secure_vector
Blinded_Point_Multiply m_base_point
PointGFp blinded_multiply(const BigInt &scalar, RandomNumberGenerator &rng)
BER_Decoder start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
GOST_3410_PublicKey()=default
BigInt reduce(const BigInt &x) const
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
std::string algo_name() const override
AlgorithmIdentifier algorithm_identifier() const override
bool on_the_curve() const
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
std::unique_ptr< PK_Ops::Verification > create_verification_op(const std::string ¶ms, const std::string &provider) const override
Modular_Reducer m_mod_order
PointGFp multi_exponentiate(const PointGFp &p1, const BigInt &z1, const PointGFp &p2, const BigInt &z2)