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

randombit / botan / 13230468750

09 Feb 2025 11:07PM UTC coverage: 91.651% (-0.008%) from 91.659%
13230468750

Pull #4647

github

web-flow
Merge 8b67be1f1 into 7deaa69bb
Pull Request #4647: Avoid using mem_ops.h or assert.h in public headers

94826 of 103464 relevant lines covered (91.65%)

11402585.19 hits per line

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

86.26
/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/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

24
namespace Botan {
25

26
size_t EC_PublicKey::key_length() const {
912✔
27
   return domain().get_p_bits();
912✔
28
}
29

30
size_t EC_PublicKey::estimated_strength() const {
532✔
31
   return ecp_work_factor(key_length());
532✔
32
}
33

34
namespace {
35

36
EC_Group_Encoding default_encoding_for(const EC_Group& group) {
24,698✔
37
   if(group.get_curve_oid().empty()) {
24,698✔
38
      return EC_Group_Encoding::Explicit;
39
   } else {
40
      return EC_Group_Encoding::NamedCurve;
24,682✔
41
   }
42
}
43

44
}  // namespace
45

46
#if defined(BOTAN_HAS_LEGACY_EC_POINT)
47
EC_PublicKey::EC_PublicKey(EC_Group group, const EC_Point& pub_point) {
14✔
48
   auto pt = EC_AffinePoint(group, pub_point);
14✔
49
   m_public_key = std::make_shared<const EC_PublicKey_Data>(std::move(group), std::move(pt));
14✔
50
   m_domain_encoding = default_encoding_for(domain());
14✔
51
}
14✔
52
#endif
53

54
EC_PublicKey::EC_PublicKey(EC_Group group, EC_AffinePoint pub_point) {
12,650✔
55
   m_public_key = std::make_shared<const EC_PublicKey_Data>(std::move(group), std::move(pub_point));
12,650✔
56
   m_domain_encoding = default_encoding_for(domain());
12,650✔
57
}
12,650✔
58

59
EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> key_bits) {
3,764✔
60
   m_public_key = std::make_shared<const EC_PublicKey_Data>(EC_Group(alg_id.parameters()), key_bits);
7,496✔
61
   m_domain_encoding = default_encoding_for(domain());
3,466✔
62
}
3,764✔
63

64
const EC_Group& EC_PublicKey::domain() const {
61,088✔
65
   BOTAN_STATE_CHECK(m_public_key != nullptr);
61,088✔
66
   return m_public_key->group();
61,088✔
67
}
68

69
#if defined(BOTAN_HAS_LEGACY_EC_POINT)
70
const EC_Point& EC_PublicKey::public_point() const {
7✔
71
   BOTAN_STATE_CHECK(m_public_key != nullptr);
7✔
72
   return m_public_key->legacy_point();
7✔
73
}
74
#endif
75

76
const EC_AffinePoint& EC_PublicKey::_public_ec_point() const {
19,126✔
77
   BOTAN_STATE_CHECK(m_public_key != nullptr);
19,126✔
78
   return m_public_key->public_key();
19,126✔
79
}
80

81
bool EC_PublicKey::check_key(RandomNumberGenerator& rng, bool /*strong*/) const {
106✔
82
   // We already checked when deserializing that the point was on the curve
83
   return domain().verify_group(rng) && !_public_ec_point().is_identity();
106✔
84
}
85

86
AlgorithmIdentifier EC_PublicKey::algorithm_identifier() const {
1,220✔
87
   return AlgorithmIdentifier(object_identifier(), DER_domain());
3,660✔
88
}
89

90
std::vector<uint8_t> EC_PublicKey::raw_public_key_bits() const {
889✔
91
   return _public_ec_point().serialize(point_encoding());
889✔
92
}
93

94
std::vector<uint8_t> EC_PublicKey::public_key_bits() const {
699✔
95
   return raw_public_key_bits();
699✔
96
}
97

98
std::vector<uint8_t> EC_PublicKey::DER_domain() const {
1,228✔
99
   return domain().DER_encode(domain_format());
1,228✔
100
}
101

102
void EC_PublicKey::set_point_encoding(EC_Point_Format enc) {
84✔
103
   if(enc != EC_Point_Format::Compressed && enc != EC_Point_Format::Uncompressed && enc != EC_Point_Format::Hybrid) {
84✔
104
      throw Invalid_Argument("Invalid point encoding for EC_PublicKey");
28✔
105
   }
106

107
   m_point_encoding = enc;
56✔
108
}
56✔
109

110
void EC_PublicKey::set_parameter_encoding(EC_Group_Encoding form) {
×
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

118
const BigInt& EC_PrivateKey::private_value() const {
17✔
119
   BOTAN_STATE_CHECK(m_private_key != nullptr);
17✔
120
   return m_private_key->legacy_bigint();
17✔
121
}
122

123
const EC_Scalar& EC_PrivateKey::_private_key() const {
7,398✔
124
   BOTAN_STATE_CHECK(m_private_key != nullptr);
7,398✔
125
   return m_private_key->private_key();
7,398✔
126
}
127

128
/**
129
* EC_PrivateKey constructor
130
*/
131
EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng,
594✔
132
                             EC_Group ec_group,
133
                             const BigInt& x,
134
                             bool with_modular_inverse) {
594✔
135
   auto scalar = (x.is_zero()) ? EC_Scalar::random(ec_group, rng) : EC_Scalar::from_bigint(ec_group, x);
1,188✔
136
   m_private_key = std::make_shared<EC_PrivateKey_Data>(std::move(ec_group), std::move(scalar));
594✔
137
   m_public_key = m_private_key->public_key(rng, with_modular_inverse);
594✔
138
   m_domain_encoding = default_encoding_for(domain());
594✔
139
}
594✔
140

141
EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng, EC_Group ec_group, bool with_modular_inverse) {
6,078✔
142
   auto scalar = EC_Scalar::random(ec_group, rng);
6,078✔
143
   m_private_key = std::make_shared<EC_PrivateKey_Data>(std::move(ec_group), std::move(scalar));
6,078✔
144
   m_public_key = m_private_key->public_key(rng, with_modular_inverse);
6,078✔
145
   m_domain_encoding = default_encoding_for(domain());
6,078✔
146
}
6,078✔
147

148
EC_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

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

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

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

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

178
   OID key_parameters;
2,180✔
179
   secure_vector<uint8_t> private_key_bits;
2,180✔
180
   secure_vector<uint8_t> public_key_bits;
2,180✔
181

182
   BER_Decoder(key_bits)
4,345✔
183
      .start_sequence()
2,165✔
184
      .decode_and_check<size_t>(1, "Unknown version code for ECC key")
2,165✔
185
      .decode(private_key_bits, ASN1_Type::OctetString)
2,161✔
186
      .decode_optional(key_parameters, ASN1_Type(0), ASN1_Class::ExplicitContextSpecific)
4,326✔
187
      .decode_optional_string(public_key_bits, ASN1_Type::BitString, 1, ASN1_Class::ExplicitContextSpecific)
2,156✔
188
      .end_cons();
2,151✔
189

190
   m_private_key = std::make_shared<EC_PrivateKey_Data>(group, private_key_bits);
2,150✔
191

192
   if(public_key_bits.empty()) {
2,086✔
193
      m_public_key = m_private_key->public_key(with_modular_inverse);
300✔
194
   } else {
195
      m_public_key = std::make_shared<EC_PublicKey_Data>(group, public_key_bits);
1,880✔
196
   }
197

198
   m_domain_encoding = default_encoding_for(domain());
3,792✔
199
}
5,276✔
200

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

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

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

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

239
}  // 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