3
* (C) 2007 Manuel Hartl, FlexSecure GmbH
4
* 2007 Falko Strenzke, FlexSecure GmbH
5
* 2008-2010,2015,2016 Jack Lloyd
8
* Botan is released under the Simplified BSD License (see license.txt)
11
#include <botan/ecdsa.h>
12
#include <botan/internal/pk_ops_impl.h>
13
#include <botan/keypair.h>
14
#include <botan/reducer.h>
15
#include <botan/emsa.h>
17
#if defined(BOTAN_HAS_RFC6979_GENERATOR)
18
#include <botan/rfc6979.h>
21
#if defined(BOTAN_HAS_BEARSSL)
22
#include <botan/internal/bearssl.h>
25
#if defined(BOTAN_HAS_OPENSSL)
26
#include <botan/internal/openssl.h>
31
bool ECDSA_PrivateKey::check_key(RandomNumberGenerator& rng,
34
if(!public_point().on_the_curve())
40
return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-256)");
46
* ECDSA signature operation
48
class ECDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA
52
ECDSA_Signature_Operation(const ECDSA_PrivateKey& ecdsa,
53
const std::string& emsa) :
54
PK_Ops::Signature_with_EMSA(emsa),
55
m_order(ecdsa.domain().get_order()),
56
m_base_point(ecdsa.domain().get_base_point(), m_order),
57
m_x(ecdsa.private_value()),
60
#if defined(BOTAN_HAS_RFC6979_GENERATOR)
61
m_rfc6979_hash = hash_for_emsa(emsa);
65
size_t max_input_bits() const override { return m_order.bits(); }
67
secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len,
68
RandomNumberGenerator& rng) override;
71
const BigInt& m_order;
72
Blinded_Point_Multiply m_base_point;
74
Modular_Reducer m_mod_order;
75
#if defined(BOTAN_HAS_RFC6979_GENERATOR)
76
std::string m_rfc6979_hash;
80
secure_vector<uint8_t>
81
ECDSA_Signature_Operation::raw_sign(const uint8_t msg[], size_t msg_len,
82
RandomNumberGenerator& rng)
84
const BigInt m(msg, msg_len);
86
#if defined(BOTAN_HAS_RFC6979_GENERATOR)
87
const BigInt k = generate_rfc6979_nonce(m_x, m_order, m, m_rfc6979_hash);
89
const BigInt k = BigInt::random_integer(rng, 1, m_order);
92
const PointGFp k_times_P = m_base_point.blinded_multiply(k, rng);
93
const BigInt r = m_mod_order.reduce(k_times_P.get_affine_x());
94
const BigInt s = m_mod_order.multiply(inverse_mod(k, m_order), mul_add(m_x, r, m));
96
// With overwhelming probability, a bug rather than actual zero r/s
97
BOTAN_ASSERT(s != 0, "invalid s");
98
BOTAN_ASSERT(r != 0, "invalid r");
100
return BigInt::encode_fixed_length_int_pair(r, s, m_order.bytes());
104
* ECDSA verification operation
106
class ECDSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA
109
ECDSA_Verification_Operation(const ECDSA_PublicKey& ecdsa,
110
const std::string& emsa) :
111
PK_Ops::Verification_with_EMSA(emsa),
112
m_base_point(ecdsa.domain().get_base_point()),
113
m_public_point(ecdsa.public_point()),
114
m_order(ecdsa.domain().get_order()),
117
//m_public_point.precompute_multiples();
120
size_t max_input_bits() const override { return m_order.bits(); }
122
bool with_recovery() const override { return false; }
124
bool verify(const uint8_t msg[], size_t msg_len,
125
const uint8_t sig[], size_t sig_len) override;
127
const PointGFp& m_base_point;
128
const PointGFp& m_public_point;
129
const BigInt& m_order;
130
// FIXME: should be offered by curve
131
Modular_Reducer m_mod_order;
134
bool ECDSA_Verification_Operation::verify(const uint8_t msg[], size_t msg_len,
135
const uint8_t sig[], size_t sig_len)
137
if(sig_len != m_order.bytes()*2)
140
BigInt e(msg, msg_len);
142
BigInt r(sig, sig_len / 2);
143
BigInt s(sig + sig_len / 2, sig_len / 2);
145
if(r <= 0 || r >= m_order || s <= 0 || s >= m_order)
148
BigInt w = inverse_mod(s, m_order);
150
const BigInt u1 = m_mod_order.reduce(e * w);
151
const BigInt u2 = m_mod_order.reduce(r * w);
152
const PointGFp R = multi_exponentiate(m_base_point, u1, m_public_point, u2);
157
const BigInt v = m_mod_order.reduce(R.get_affine_x());
163
std::unique_ptr<PK_Ops::Verification>
164
ECDSA_PublicKey::create_verification_op(const std::string& params,
165
const std::string& provider) const
167
#if defined(BOTAN_HAS_BEARSSL)
168
if(provider == "bearssl" || provider.empty())
172
return make_bearssl_ecdsa_ver_op(*this, params);
174
catch(Lookup_Error& e)
176
if(provider == "bearssl")
182
#if defined(BOTAN_HAS_OPENSSL)
183
if(provider == "openssl" || provider.empty())
187
return make_openssl_ecdsa_ver_op(*this, params);
189
catch(Lookup_Error& e)
191
if(provider == "openssl")
197
if(provider == "base" || provider.empty())
198
return std::unique_ptr<PK_Ops::Verification>(new ECDSA_Verification_Operation(*this, params));
200
throw Provider_Not_Found(algo_name(), provider);
203
std::unique_ptr<PK_Ops::Signature>
204
ECDSA_PrivateKey::create_signature_op(RandomNumberGenerator& /*rng*/,
205
const std::string& params,
206
const std::string& provider) const
208
#if defined(BOTAN_HAS_BEARSSL)
209
if(provider == "bearssl" || provider.empty())
213
return make_bearssl_ecdsa_sig_op(*this, params);
215
catch(Lookup_Error& e)
217
if(provider == "bearssl")
223
#if defined(BOTAN_HAS_OPENSSL)
224
if(provider == "openssl" || provider.empty())
228
return make_openssl_ecdsa_sig_op(*this, params);
230
catch(Lookup_Error& e)
232
if(provider == "openssl")
238
if(provider == "base" || provider.empty())
239
return std::unique_ptr<PK_Ops::Signature>(new ECDSA_Signature_Operation(*this, params));
241
throw Provider_Not_Found(algo_name(), provider);