9#include <botan/ecgdsa.h>
11#include <botan/internal/keypair.h>
12#include <botan/internal/pk_ops_impl.h>
39 ECGDSA_Signature_Operation(
const ECGDSA_PrivateKey& ecgdsa, std::string_view emsa) :
40 PK_Ops::Signature_with_Hash(emsa), m_group(ecgdsa.domain()), m_x(ecgdsa._private_key()) {}
42 std::vector<uint8_t> raw_sign(std::span<const uint8_t> msg, RandomNumberGenerator& rng)
override;
44 size_t signature_length()
const override {
return 2 * m_group.get_order_bytes(); }
46 AlgorithmIdentifier algorithm_identifier()
const override;
49 const EC_Group m_group;
51 std::vector<BigInt> m_ws;
54AlgorithmIdentifier ECGDSA_Signature_Operation::algorithm_identifier()
const {
55 const std::string full_name =
"ECGDSA/" + hash_function();
56 const OID oid = OID::from_string(full_name);
57 return AlgorithmIdentifier(oid, AlgorithmIdentifier::USE_EMPTY_PARAM);
60std::vector<uint8_t> ECGDSA_Signature_Operation::raw_sign(std::span<const uint8_t> msg, RandomNumberGenerator& rng) {
61 const auto m = EC_Scalar::from_bytes_with_trunc(m_group, msg);
63 const auto k = EC_Scalar::random(m_group, rng);
65 const auto r = EC_Scalar::gk_x_mod_order(k, rng, m_ws);
67 const auto s = m_x * ((k * r) - m);
70 if(r.is_zero() || s.is_zero()) {
71 throw Internal_Error(
"During ECGDSA signature generated zero r/s");
74 return EC_Scalar::serialize_pair(r, s);
80class ECGDSA_Verification_Operation
final :
public PK_Ops::Verification_with_Hash {
82 ECGDSA_Verification_Operation(
const ECGDSA_PublicKey& ecgdsa, std::string_view padding) :
83 PK_Ops::Verification_with_Hash(padding), m_group(ecgdsa.domain()), m_gy_mul(ecgdsa._public_key()) {}
85 ECGDSA_Verification_Operation(
const ECGDSA_PublicKey& ecgdsa,
const AlgorithmIdentifier& alg_id) :
86 PK_Ops::Verification_with_Hash(alg_id,
"ECGDSA"),
87 m_group(ecgdsa.domain()),
88 m_gy_mul(ecgdsa._public_key()) {}
90 bool verify(std::span<const uint8_t> msg, std::span<const uint8_t> sig)
override;
93 const EC_Group m_group;
94 const EC_Group::Mul2Table m_gy_mul;
97bool ECGDSA_Verification_Operation::verify(std::span<const uint8_t> msg, std::span<const uint8_t> sig) {
98 if(
auto rs = EC_Scalar::deserialize_pair(m_group, sig)) {
99 const auto& [r, s] = rs.value();
101 if(r.is_nonzero() && s.is_nonzero()) {
102 const auto m = EC_Scalar::from_bytes_with_trunc(m_group, msg);
104 const auto w = r.invert();
117 return std::make_unique<ECGDSA_PrivateKey>(rng, domain());
121 std::string_view provider)
const {
122 if(provider ==
"base" || provider.empty()) {
123 return std::make_unique<ECGDSA_Verification_Operation>(*
this, params);
130 if(provider ==
"base" || provider.empty()) {
131 return std::make_unique<ECGDSA_Verification_Operation>(*
this, signature_algorithm);
138 std::string_view params,
139 std::string_view provider)
const {
140 if(provider ==
"base" || provider.empty()) {
141 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
bool mul2_vartime_x_mod_order_eq(const EC_Scalar &v, const EC_Scalar &x, const EC_Scalar &y) 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)