9#include <botan/ecgdsa.h>
11#include <botan/reducer.h>
12#include <botan/internal/keypair.h>
13#include <botan/internal/pk_ops_impl.h>
14#include <botan/internal/point_mul.h>
41 ECGDSA_Signature_Operation(
const ECGDSA_PrivateKey& ecgdsa, std::string_view emsa) :
42 PK_Ops::Signature_with_Hash(emsa), m_group(ecgdsa.domain()), m_x(ecgdsa.private_value()) {}
44 secure_vector<uint8_t> raw_sign(
const uint8_t msg[],
size_t msg_len, RandomNumberGenerator& rng)
override;
46 size_t signature_length()
const override {
return 2 * m_group.get_order_bytes(); }
48 AlgorithmIdentifier algorithm_identifier()
const override;
51 const EC_Group m_group;
53 std::vector<BigInt> m_ws;
56AlgorithmIdentifier ECGDSA_Signature_Operation::algorithm_identifier()
const {
57 const std::string full_name =
"ECGDSA/" + hash_function();
58 const OID oid = OID::from_string(full_name);
59 return AlgorithmIdentifier(oid, AlgorithmIdentifier::USE_EMPTY_PARAM);
62secure_vector<uint8_t> ECGDSA_Signature_Operation::raw_sign(
const uint8_t msg[],
64 RandomNumberGenerator& rng) {
65 const BigInt m = BigInt::from_bytes_with_max_bits(msg, msg_len, m_group.
get_order_bits());
76 if(r.is_zero() || s.is_zero()) {
77 throw Internal_Error(
"During ECGDSA signature generated zero r/s");
80 return BigInt::encode_fixed_length_int_pair(r, s, m_group.
get_order_bytes());
86class ECGDSA_Verification_Operation
final :
public PK_Ops::Verification_with_Hash {
88 ECGDSA_Verification_Operation(
const ECGDSA_PublicKey& ecgdsa, std::string_view padding) :
89 PK_Ops::Verification_with_Hash(padding),
90 m_group(ecgdsa.domain()),
91 m_gy_mul(m_group.get_base_point(), ecgdsa.public_point()) {}
93 ECGDSA_Verification_Operation(
const ECGDSA_PublicKey& ecgdsa,
const AlgorithmIdentifier& alg_id) :
94 PK_Ops::Verification_with_Hash(alg_id,
"ECGDSA"),
95 m_group(ecgdsa.domain()),
96 m_gy_mul(m_group.get_base_point(), ecgdsa.public_point()) {}
98 bool verify(
const uint8_t msg[],
size_t msg_len,
const uint8_t sig[],
size_t sig_len)
override;
101 const EC_Group m_group;
102 const EC_Point_Multi_Point_Precompute m_gy_mul;
105bool ECGDSA_Verification_Operation::verify(
const uint8_t msg[],
size_t msg_len,
const uint8_t sig[],
size_t sig_len) {
110 const BigInt e = BigInt::from_bytes_with_max_bits(msg, msg_len, m_group.
get_order_bits());
112 const BigInt r(sig, sig_len / 2);
113 const BigInt s(sig + sig_len / 2, sig_len / 2);
123 const EC_Point R = m_gy_mul.
multi_exp(u1, u2);
129 const BigInt v = m_group.
mod_order(R.get_affine_x());
136 return std::make_unique<ECGDSA_PrivateKey>(rng, domain());
140 std::string_view provider)
const {
141 if(provider ==
"base" || provider.empty()) {
142 return std::make_unique<ECGDSA_Verification_Operation>(*
this, params);
149 if(provider ==
"base" || provider.empty()) {
150 return std::make_unique<ECGDSA_Verification_Operation>(*
this, signature_algorithm);
157 std::string_view params,
158 std::string_view provider)
const {
159 if(provider ==
"base" || provider.empty()) {
160 return std::make_unique<ECGDSA_Signature_Operation>(*
this, params);
std::unique_ptr< Public_Key > public_key() const override
bool check_key(RandomNumberGenerator &rng, bool) const override
std::unique_ptr< PK_Ops::Signature > create_signature_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const override
std::unique_ptr< PK_Ops::Verification > create_verification_op(std::string_view params, std::string_view provider) const override
std::unique_ptr< PK_Ops::Verification > create_x509_verification_op(const AlgorithmIdentifier &signature_algorithm, std::string_view provider) const override
std::unique_ptr< Private_Key > generate_another(RandomNumberGenerator &rng) const final
BigInt blinded_base_point_multiply_x(const BigInt &k, RandomNumberGenerator &rng, std::vector< BigInt > &ws) const
BigInt mod_order(const BigInt &x) const
BigInt multiply_mod_order(const BigInt &x, const BigInt &y) const
const BigInt & get_order() const
BigInt inverse_mod_order(const BigInt &x) const
BigInt random_scalar(RandomNumberGenerator &rng) const
size_t get_order_bits() const
size_t get_order_bytes() const
EC_Point multi_exp(const BigInt &k1, const BigInt &k2) const
bool check_key(RandomNumberGenerator &rng, bool strong) const override
const EC_Group & domain() const
const EC_Point & public_point() const
int(* final)(unsigned char *, CTX *)
bool signature_consistency_check(RandomNumberGenerator &rng, const Private_Key &private_key, const Public_Key &public_key, std::string_view padding)