Botan 3.8.1
Crypto and TLS for C&
ecc_key.cpp
Go to the documentation of this file.
1/*
2* ECC Key implemenation
3* (C) 2007 Manuel Hartl, FlexSecure GmbH
4* Falko Strenzke, FlexSecure GmbH
5* 2008-2010 Jack Lloyd
6*
7* Botan is released under the Simplified BSD License (see license.txt)
8*/
9
10#include <botan/ecc_key.h>
11
12#include <botan/assert.h>
13#include <botan/ber_dec.h>
14#include <botan/der_enc.h>
15#include <botan/secmem.h>
16#include <botan/internal/ec_key_data.h>
17#include <botan/internal/fmt.h>
18#include <botan/internal/workfactor.h>
19
20#if defined(BOTAN_HAS_LEGACY_EC_POINT)
21 #include <botan/ec_point.h>
22#endif
23
24namespace Botan {
25
27 return domain().get_p_bits();
28}
29
33
34namespace {
35
36EC_Group_Encoding default_encoding_for(const EC_Group& group) {
37 if(group.get_curve_oid().empty()) {
39 } else {
41 }
42}
43
44} // namespace
45
46#if defined(BOTAN_HAS_LEGACY_EC_POINT)
47EC_PublicKey::EC_PublicKey(EC_Group group, const EC_Point& pub_point) {
48 auto pt = EC_AffinePoint(group, pub_point);
49 m_public_key = std::make_shared<const EC_PublicKey_Data>(std::move(group), std::move(pt));
50 m_domain_encoding = default_encoding_for(domain());
51}
52#endif
53
55 m_public_key = std::make_shared<const EC_PublicKey_Data>(std::move(group), std::move(pub_point));
56 m_domain_encoding = default_encoding_for(domain());
57}
58
59EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> key_bits) {
60 m_public_key = std::make_shared<const EC_PublicKey_Data>(EC_Group(alg_id.parameters()), key_bits);
61 m_domain_encoding = default_encoding_for(domain());
62}
63
66 return m_public_key->group();
67}
68
69#if defined(BOTAN_HAS_LEGACY_EC_POINT)
70const EC_Point& EC_PublicKey::public_point() const {
72 return m_public_key->legacy_point();
73}
74#endif
75
78 return m_public_key->public_key();
79}
80
81bool EC_PublicKey::check_key(RandomNumberGenerator& rng, bool /*strong*/) const {
82 // We already checked when deserializing that the point was on the curve
83 return domain().verify_group(rng) && !_public_ec_point().is_identity();
84}
85
89
90std::vector<uint8_t> EC_PublicKey::raw_public_key_bits() const {
92}
93
94std::vector<uint8_t> EC_PublicKey::public_key_bits() const {
95 return raw_public_key_bits();
96}
97
98std::vector<uint8_t> EC_PublicKey::DER_domain() const {
100}
101
104 throw Invalid_Argument("Invalid point encoding for EC_PublicKey");
105 }
106
107 m_point_encoding = enc;
108}
109
111 if(form == EC_Group_Encoding::NamedCurve && domain().get_curve_oid().empty()) {
112 throw Invalid_Argument("Cannot used NamedCurve encoding for a curve without an OID");
113 }
114
115 m_domain_encoding = form;
116}
117
120 return m_private_key->legacy_bigint();
121}
122
125 return m_private_key->private_key();
126}
127
128/**
129* EC_PrivateKey constructor
130*/
132 EC_Group ec_group,
133 const BigInt& x,
134 bool with_modular_inverse) {
135 auto scalar = (x.is_zero()) ? EC_Scalar::random(ec_group, rng) : EC_Scalar::from_bigint(ec_group, x);
136 m_private_key = std::make_shared<EC_PrivateKey_Data>(std::move(ec_group), std::move(scalar));
137 m_public_key = m_private_key->public_key(rng, with_modular_inverse);
138 m_domain_encoding = default_encoding_for(domain());
139}
140
141EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng, EC_Group ec_group, bool with_modular_inverse) {
142 auto scalar = EC_Scalar::random(ec_group, rng);
143 m_private_key = std::make_shared<EC_PrivateKey_Data>(std::move(ec_group), std::move(scalar));
144 m_public_key = m_private_key->public_key(rng, with_modular_inverse);
145 m_domain_encoding = default_encoding_for(domain());
146}
147
148EC_PrivateKey::EC_PrivateKey(EC_Group ec_group, EC_Scalar x, bool with_modular_inverse) {
149 m_private_key = std::make_shared<EC_PrivateKey_Data>(std::move(ec_group), std::move(x));
150 m_public_key = m_private_key->public_key(with_modular_inverse);
151 m_domain_encoding = default_encoding_for(domain());
152}
153
158
160 BOTAN_STATE_CHECK(m_private_key != nullptr && m_public_key != nullptr);
161
162 return DER_Encoder()
164 .encode(static_cast<size_t>(1))
167 .encode(m_public_key->public_key().serialize_uncompressed(), ASN1_Type::BitString)
168 .end_cons()
169 .end_cons()
170 .get_contents();
171}
172
174 std::span<const uint8_t> key_bits,
175 bool with_modular_inverse) {
176 EC_Group group(alg_id.parameters());
177
178 OID key_parameters;
181
182 BER_Decoder(key_bits)
184 .decode_and_check<size_t>(1, "Unknown version code for ECC key")
186 .decode_optional(key_parameters, ASN1_Type(0), ASN1_Class::ExplicitContextSpecific)
188 .end_cons();
189
190 m_private_key = std::make_shared<EC_PrivateKey_Data>(group, private_key_bits);
191
192 if(public_key_bits.empty()) {
193 m_public_key = m_private_key->public_key(with_modular_inverse);
194 } else {
195 m_public_key = std::make_shared<EC_PublicKey_Data>(group, public_key_bits);
196 }
197
198 m_domain_encoding = default_encoding_for(domain());
199}
200
201bool EC_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const {
202 if(!m_private_key) {
203 return false;
204 }
205
206 return EC_PublicKey::check_key(rng, strong);
207}
208
209const BigInt& EC_PublicKey::get_int_field(std::string_view field) const {
210 if(field == "public_x" || field == "public_y") {
211 throw Not_Implemented(fmt("EC_PublicKey::get_int_field no longer implements getter for {}", field));
212 } else if(field == "base_x") {
213 return this->domain().get_g_x();
214 } else if(field == "base_y") {
215 return this->domain().get_g_y();
216 } else if(field == "p") {
217 return this->domain().get_p();
218 } else if(field == "a") {
219 return this->domain().get_a();
220 } else if(field == "b") {
221 return this->domain().get_b();
222 } else if(field == "cofactor") {
223 return this->domain().get_cofactor();
224 } else if(field == "order") {
225 return this->domain().get_order();
226 } else {
227 return Public_Key::get_int_field(field);
228 }
229}
230
231const BigInt& EC_PrivateKey::get_int_field(std::string_view field) const {
232 if(field == "x") {
233 return this->private_value();
234 } else {
235 return EC_PublicKey::get_int_field(field);
236 }
237}
238
239} // namespace Botan
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:43
const std::vector< uint8_t > & parameters() const
Definition asn1_obj.h:474
virtual const BigInt & get_int_field(std::string_view field) const
Definition pk_keys.cpp:18
virtual OID object_identifier() const
Definition pk_keys.cpp:22
BER_Decoder start_sequence()
Definition ber_dec.h:122
BER_Decoder & decode_and_check(const T &expected, std::string_view error_msg)
Definition ber_dec.h:271
bool is_zero() const
Definition bigint.h:457
secure_vector< uint8_t > get_contents()
Definition der_enc.cpp:132
DER_Encoder & start_explicit_context_specific(uint32_t tag)
Definition der_enc.h:72
DER_Encoder & start_sequence()
Definition der_enc.h:64
DER_Encoder & end_cons()
Definition der_enc.cpp:171
DER_Encoder & encode(bool b)
Definition der_enc.cpp:250
bool is_identity() const
Return true if this point is the identity element.
std::vector< uint8_t > serialize(EC_Point_Format format) const
Return an encoding depending on the requested format.
const BigInt & get_b() const
Definition ec_group.cpp:544
const BigInt & get_a() const
Definition ec_group.cpp:540
const BigInt & get_g_y() const
Definition ec_group.cpp:592
const BigInt & get_cofactor() const
Definition ec_group.cpp:596
const BigInt & get_p() const
Definition ec_group.cpp:536
bool verify_group(RandomNumberGenerator &rng, bool strong=false) const
Definition ec_group.cpp:676
const BigInt & get_order() const
Definition ec_group.cpp:584
size_t get_p_bits() const
Definition ec_group.cpp:520
const BigInt & get_g_x() const
Definition ec_group.cpp:588
const OID & get_curve_oid() const
Definition ec_group.cpp:604
std::vector< uint8_t > DER_encode(EC_Group_Encoding form) const
Definition ec_group.cpp:626
const EC_Scalar & _private_key() const
Definition ecc_key.cpp:123
const BigInt & private_value() const
Definition ecc_key.cpp:118
secure_vector< uint8_t > raw_private_key_bits() const final
Definition ecc_key.cpp:154
std::shared_ptr< const EC_PrivateKey_Data > m_private_key
Definition ecc_key.h:219
bool check_key(RandomNumberGenerator &rng, bool strong) const override
Definition ecc_key.cpp:201
const BigInt & get_int_field(std::string_view field) const final
Definition ecc_key.cpp:231
secure_vector< uint8_t > private_key_bits() const final
Definition ecc_key.cpp:159
const EC_Group & domain() const
Definition ecc_key.cpp:64
std::vector< uint8_t > DER_domain() const
Definition ecc_key.cpp:98
void set_parameter_encoding(EC_Group_Encoding enc)
Definition ecc_key.cpp:110
EC_Point_Format m_point_encoding
Definition ecc_key.h:137
EC_Group_Encoding m_domain_encoding
Definition ecc_key.h:136
size_t estimated_strength() const override
Definition ecc_key.cpp:30
AlgorithmIdentifier algorithm_identifier() const override
Definition ecc_key.cpp:86
size_t key_length() const override
Definition ecc_key.cpp:26
EC_Group_Encoding domain_format() const
Definition ecc_key.h:92
std::shared_ptr< const EC_PublicKey_Data > m_public_key
Definition ecc_key.h:135
std::vector< uint8_t > raw_public_key_bits() const override
Definition ecc_key.cpp:90
void set_point_encoding(EC_Point_Format enc)
Definition ecc_key.cpp:102
const BigInt & get_int_field(std::string_view field) const override
Definition ecc_key.cpp:209
EC_PublicKey()=default
EC_Point_Format point_encoding() const
Definition ecc_key.h:98
const EC_AffinePoint & _public_ec_point() const
Definition ecc_key.cpp:76
bool check_key(RandomNumberGenerator &rng, bool strong) const override
Definition ecc_key.cpp:81
std::vector< uint8_t > public_key_bits() const override
Definition ecc_key.cpp:94
static EC_Scalar from_bigint(const EC_Group &group, const BigInt &bn)
Definition ec_scalar.cpp:65
static EC_Scalar random(const EC_Group &group, RandomNumberGenerator &rng)
Definition ec_scalar.cpp:57
bool empty() const
Definition asn1_obj.h:266
size_t ecp_work_factor(size_t bits)
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
ASN1_Type
Definition asn1_obj.h:44
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:65
EC_Group_Encoding
Definition ec_group.h:36