• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 11902390173

18 Nov 2024 10:36PM UTC coverage: 91.063% (-0.01%) from 91.073%
11902390173

push

github

web-flow
Merge pull request #4437 from Rohde-Schwarz/feature/ecc_constructor

90631 of 99526 relevant lines covered (91.06%)

9447600.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.48
/src/lib/pubkey/ecc_key/ecc_key.cpp
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/ber_dec.h>
13
#include <botan/der_enc.h>
14
#include <botan/ec_point.h>
15
#include <botan/numthry.h>
16
#include <botan/secmem.h>
17
#include <botan/internal/ec_key_data.h>
18
#include <botan/internal/fmt.h>
19
#include <botan/internal/workfactor.h>
20

21
namespace Botan {
22

23
size_t EC_PublicKey::key_length() const {
918✔
24
   return domain().get_p_bits();
918✔
25
}
26

27
size_t EC_PublicKey::estimated_strength() const {
536✔
28
   return ecp_work_factor(key_length());
536✔
29
}
30

31
namespace {
32

33
EC_Group_Encoding default_encoding_for(const EC_Group& group) {
23,155✔
34
   if(group.get_curve_oid().empty()) {
23,155✔
35
      return EC_Group_Encoding::Explicit;
36
   } else {
37
      return EC_Group_Encoding::NamedCurve;
23,139✔
38
   }
39
}
40

41
}  // namespace
42

43
EC_PublicKey::EC_PublicKey(EC_Group group, const EC_Point& pub_point) {
12,416✔
44
   auto pt = EC_AffinePoint(group, pub_point);
12,416✔
45
   m_public_key = std::make_shared<const EC_PublicKey_Data>(std::move(group), std::move(pt));
12,416✔
46
   m_domain_encoding = default_encoding_for(domain());
12,416✔
47
}
12,416✔
48

49
EC_PublicKey::EC_PublicKey(EC_Group group, EC_AffinePoint pub_point) {
40✔
50
   m_public_key = std::make_shared<const EC_PublicKey_Data>(std::move(group), std::move(pub_point));
40✔
51
   m_domain_encoding = default_encoding_for(domain());
40✔
52
}
40✔
53

54
EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> key_bits) {
3,770✔
55
   m_public_key = std::make_shared<const EC_PublicKey_Data>(EC_Group(alg_id.parameters()), key_bits);
7,508✔
56
   m_domain_encoding = default_encoding_for(domain());
3,592✔
57
}
3,770✔
58

59
const EC_Group& EC_PublicKey::domain() const {
57,022✔
60
   BOTAN_STATE_CHECK(m_public_key != nullptr);
57,022✔
61
   return m_public_key->group();
57,022✔
62
}
63

64
const EC_Point& EC_PublicKey::public_point() const {
7,271✔
65
   BOTAN_STATE_CHECK(m_public_key != nullptr);
7,271✔
66
   return m_public_key->legacy_point();
7,271✔
67
}
68

69
const EC_AffinePoint& EC_PublicKey::_public_key() const {
11,707✔
70
   BOTAN_STATE_CHECK(m_public_key != nullptr);
11,707✔
71
   return m_public_key->public_key();
11,707✔
72
}
73

74
bool EC_PublicKey::check_key(RandomNumberGenerator& rng, bool /*strong*/) const {
106✔
75
   return domain().verify_group(rng) && domain().verify_public_element(public_point());
106✔
76
}
77

78
AlgorithmIdentifier EC_PublicKey::algorithm_identifier() const {
1,220✔
79
   return AlgorithmIdentifier(object_identifier(), DER_domain());
3,660✔
80
}
81

82
std::vector<uint8_t> EC_PublicKey::raw_public_key_bits() const {
727✔
83
   return public_point().encode(point_encoding());
727✔
84
}
85

86
std::vector<uint8_t> EC_PublicKey::public_key_bits() const {
600✔
87
   return raw_public_key_bits();
600✔
88
}
89

90
std::vector<uint8_t> EC_PublicKey::DER_domain() const {
1,228✔
91
   return domain().DER_encode(domain_format());
1,228✔
92
}
93

94
void EC_PublicKey::set_point_encoding(EC_Point_Format enc) {
3✔
95
   if(enc != EC_Point_Format::Compressed && enc != EC_Point_Format::Uncompressed && enc != EC_Point_Format::Hybrid) {
3✔
96
      throw Invalid_Argument("Invalid point encoding for EC_PublicKey");
1✔
97
   }
98

99
   m_point_encoding = enc;
2✔
100
}
2✔
101

102
void EC_PublicKey::set_parameter_encoding(EC_Group_Encoding form) {
×
103
   if(form == EC_Group_Encoding::NamedCurve && domain().get_curve_oid().empty()) {
×
104
      throw Invalid_Argument("Cannot used NamedCurve encoding for a curve without an OID");
×
105
   }
106

107
   m_domain_encoding = form;
×
108
}
×
109

110
const BigInt& EC_PrivateKey::private_value() const {
17✔
111
   BOTAN_STATE_CHECK(m_private_key != nullptr);
17✔
112
   return m_private_key->legacy_bigint();
17✔
113
}
114

115
const EC_Scalar& EC_PrivateKey::_private_key() const {
7,402✔
116
   BOTAN_STATE_CHECK(m_private_key != nullptr);
7,402✔
117
   return m_private_key->private_key();
7,402✔
118
}
119

120
/**
121
* EC_PrivateKey constructor
122
*/
123
EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng,
658✔
124
                             EC_Group ec_group,
125
                             const BigInt& x,
126
                             bool with_modular_inverse) {
658✔
127
   auto scalar = (x.is_zero()) ? EC_Scalar::random(ec_group, rng) : EC_Scalar::from_bigint(ec_group, x);
1,316✔
128
   m_private_key = std::make_shared<EC_PrivateKey_Data>(std::move(ec_group), std::move(scalar));
658✔
129
   m_public_key = m_private_key->public_key(rng, with_modular_inverse);
658✔
130
   m_domain_encoding = default_encoding_for(domain());
658✔
131
}
658✔
132

133
EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng, EC_Group ec_group, bool with_modular_inverse) {
5,982✔
134
   auto scalar = EC_Scalar::random(ec_group, rng);
5,982✔
135
   m_private_key = std::make_shared<EC_PrivateKey_Data>(std::move(ec_group), std::move(scalar));
5,982✔
136
   m_public_key = m_private_key->public_key(rng, with_modular_inverse);
5,982✔
137
   m_domain_encoding = default_encoding_for(domain());
5,982✔
138
}
5,982✔
139

140
EC_PrivateKey::EC_PrivateKey(EC_Group group, const BigInt& bn_scalar, bool with_modular_inverse) {
×
141
   auto scalar = EC_Scalar::from_bigint(group, bn_scalar);
×
142
   m_private_key = std::make_shared<EC_PrivateKey_Data>(std::move(group), std::move(scalar));
×
143
   m_public_key = m_private_key->public_key(with_modular_inverse);
×
144
   m_domain_encoding = default_encoding_for(domain());
×
145
}
×
146

147
EC_PrivateKey::EC_PrivateKey(EC_Group ec_group, EC_Scalar x, bool with_modular_inverse) {
×
148
   m_private_key = std::make_shared<EC_PrivateKey_Data>(std::move(ec_group), std::move(x));
×
149
   m_public_key = m_private_key->public_key(with_modular_inverse);
×
150
   m_domain_encoding = default_encoding_for(domain());
×
151
}
×
152

153
secure_vector<uint8_t> EC_PrivateKey::raw_private_key_bits() const {
761✔
154
   BOTAN_STATE_CHECK(m_private_key != nullptr);
761✔
155
   return m_private_key->serialize<secure_vector<uint8_t>>();
761✔
156
}
157

158
secure_vector<uint8_t> EC_PrivateKey::private_key_bits() const {
758✔
159
   BOTAN_STATE_CHECK(m_private_key != nullptr && m_public_key != nullptr);
758✔
160

161
   return DER_Encoder()
758✔
162
      .start_sequence()
758✔
163
      .encode(static_cast<size_t>(1))
758✔
164
      .encode(raw_private_key_bits(), ASN1_Type::OctetString)
2,274✔
165
      .start_explicit_context_specific(1)
758✔
166
      .encode(m_public_key->public_key().serialize_uncompressed(), ASN1_Type::BitString)
1,516✔
167
      .end_cons()
758✔
168
      .end_cons()
758✔
169
      .get_contents();
1,516✔
170
}
171

172
EC_PrivateKey::EC_PrivateKey(const AlgorithmIdentifier& alg_id,
1,399✔
173
                             std::span<const uint8_t> key_bits,
174
                             bool with_modular_inverse) {
1,399✔
175
   EC_Group group(alg_id.parameters());
1,399✔
176

177
   OID key_parameters;
1,051✔
178
   secure_vector<uint8_t> private_key_bits;
1,051✔
179
   secure_vector<uint8_t> public_key_bits;
1,051✔
180

181
   BER_Decoder(key_bits)
2,087✔
182
      .start_sequence()
1,036✔
183
      .decode_and_check<size_t>(1, "Unknown version code for ECC key")
1,036✔
184
      .decode(private_key_bits, ASN1_Type::OctetString)
1,032✔
185
      .decode_optional(key_parameters, ASN1_Type(0), ASN1_Class::ExplicitContextSpecific)
2,068✔
186
      .decode_optional_string(public_key_bits, ASN1_Type::BitString, 1, ASN1_Class::ExplicitContextSpecific)
1,027✔
187
      .end_cons();
1,022✔
188

189
   m_private_key = std::make_shared<EC_PrivateKey_Data>(group, private_key_bits);
1,021✔
190

191
   if(public_key_bits.empty()) {
476✔
192
      m_public_key = m_private_key->public_key(with_modular_inverse);
3✔
193
   } else {
194
      m_public_key = std::make_shared<EC_PublicKey_Data>(group, public_key_bits);
1,048✔
195
   }
196

197
   m_domain_encoding = default_encoding_for(domain());
934✔
198
}
3,618✔
199

200
bool EC_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const {
52✔
201
   if(!m_private_key) {
52✔
202
      return false;
203
   }
204

205
   return EC_PublicKey::check_key(rng, strong);
52✔
206
}
207

208
const BigInt& EC_PublicKey::get_int_field(std::string_view field) const {
2✔
209
   if(field == "public_x" || field == "public_y") {
2✔
210
      throw Not_Implemented(fmt("EC_PublicKey::get_int_field no longer implements getter for {}", field));
×
211
   } else if(field == "base_x") {
2✔
212
      return this->domain().get_g_x();
×
213
   } else if(field == "base_y") {
2✔
214
      return this->domain().get_g_y();
×
215
   } else if(field == "p") {
2✔
216
      return this->domain().get_p();
×
217
   } else if(field == "a") {
2✔
218
      return this->domain().get_a();
×
219
   } else if(field == "b") {
2✔
220
      return this->domain().get_b();
×
221
   } else if(field == "cofactor") {
2✔
222
      return this->domain().get_cofactor();
×
223
   } else if(field == "order") {
2✔
224
      return this->domain().get_order();
×
225
   } else {
226
      return Public_Key::get_int_field(field);
2✔
227
   }
228
}
229

230
const BigInt& EC_PrivateKey::get_int_field(std::string_view field) const {
10✔
231
   if(field == "x") {
10✔
232
      return this->private_value();
9✔
233
   } else {
234
      return EC_PublicKey::get_int_field(field);
1✔
235
   }
236
}
237

238
}  // namespace Botan
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc