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

randombit / botan / 5230455705

10 Jun 2023 02:30PM UTC coverage: 91.715% (-0.03%) from 91.746%
5230455705

push

github

randombit
Merge GH #3584 Change clang-format AllowShortFunctionsOnASingleLine config from All to Inline

77182 of 84154 relevant lines covered (91.72%)

11975295.43 hits per line

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

80.77
/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/workfactor.h>
18

19
namespace Botan {
20

21
size_t EC_PublicKey::key_length() const {
792✔
22
   return domain().get_p_bits();
792✔
23
}
24

25
size_t EC_PublicKey::estimated_strength() const {
296✔
26
   return ecp_work_factor(key_length());
296✔
27
}
28

29
namespace {
30

31
EC_Group_Encoding default_encoding_for(EC_Group& group) {
16,624✔
32
   if(group.get_curve_oid().empty()) {
16,562✔
33
      return EC_Group_Encoding::Explicit;
34
   } else {
35
      return EC_Group_Encoding::NamedCurve;
16,533✔
36
   }
37
}
38

39
}  // namespace
40

41
EC_PublicKey::EC_PublicKey(const EC_Group& dom_par, const EC_Point& pub_point) :
12,392✔
42
      m_domain_params(dom_par), m_public_key(pub_point), m_domain_encoding(default_encoding_for(m_domain_params)) {}
24,784✔
43

44
EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id, std::span<const uint8_t> key_bits) :
2,457✔
45
      m_domain_params{EC_Group(alg_id.parameters())},
2,429✔
46
      m_public_key{domain().OS2ECP(key_bits)},
2,429✔
47
      m_domain_encoding(default_encoding_for(m_domain_params)) {}
7,113✔
48

49
bool EC_PublicKey::check_key(RandomNumberGenerator& rng, bool /*strong*/) const {
79✔
50
   return m_domain_params.verify_group(rng) && m_domain_params.verify_public_element(public_point());
79✔
51
}
52

53
AlgorithmIdentifier EC_PublicKey::algorithm_identifier() const {
700✔
54
   return AlgorithmIdentifier(object_identifier(), DER_domain());
1,400✔
55
}
56

57
std::vector<uint8_t> EC_PublicKey::public_key_bits() const {
371✔
58
   return public_point().encode(point_encoding());
371✔
59
}
60

61
void EC_PublicKey::set_point_encoding(EC_Point_Format enc) {
3✔
62
   if(enc != EC_Point_Format::Compressed && enc != EC_Point_Format::Uncompressed && enc != EC_Point_Format::Hybrid) {
3✔
63
      throw Invalid_Argument("Invalid point encoding for EC_PublicKey");
1✔
64
   }
65

66
   m_point_encoding = enc;
2✔
67
}
2✔
68

69
void EC_PublicKey::set_parameter_encoding(EC_Group_Encoding form) {
×
70
   if(form == EC_Group_Encoding::NamedCurve && m_domain_params.get_curve_oid().empty()) {
×
71
      throw Invalid_Argument("Cannot used NamedCurve encoding for a curve without an OID");
×
72
   }
73

74
   m_domain_encoding = form;
×
75
}
×
76

77
const BigInt& EC_PrivateKey::private_value() const {
1,205✔
78
   if(m_private_key == 0) {
1,205✔
79
      throw Invalid_State("EC_PrivateKey::private_value - uninitialized");
×
80
   }
81

82
   return m_private_key;
1,205✔
83
}
84

85
/**
86
* EC_PrivateKey constructor
87
*/
88
EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng,
1,028✔
89
                             const EC_Group& ec_group,
90
                             const BigInt& x,
91
                             bool with_modular_inverse) {
1,028✔
92
   m_domain_params = ec_group;
1,028✔
93
   m_domain_encoding = default_encoding_for(m_domain_params);
1,028✔
94

95
   if(x == 0) {
1,028✔
96
      m_private_key = ec_group.random_scalar(rng);
996✔
97
   } else {
98
      m_private_key = x;
530✔
99
   }
100

101
   std::vector<BigInt> ws;
1,028✔
102

103
   if(with_modular_inverse) {
1,028✔
104
      // ECKCDSA
105
      m_public_key = domain().blinded_base_point_multiply(m_domain_params.inverse_mod_order(m_private_key), rng, ws);
171✔
106
   } else {
107
      m_public_key = domain().blinded_base_point_multiply(m_private_key, rng, ws);
1,942✔
108
   }
109

110
   BOTAN_ASSERT(m_public_key.on_the_curve(), "Generated public key point was on the curve");
1,028✔
111
}
1,028✔
112

113
secure_vector<uint8_t> EC_PrivateKey::raw_private_key_bits() const {
×
114
   return BigInt::encode_locked(m_private_key);
×
115
}
116

117
secure_vector<uint8_t> EC_PrivateKey::private_key_bits() const {
344✔
118
   return DER_Encoder()
344✔
119
      .start_sequence()
344✔
120
      .encode(static_cast<size_t>(1))
344✔
121
      .encode(BigInt::encode_1363(m_private_key, m_private_key.bytes()), ASN1_Type::OctetString)
1,032✔
122
      .start_explicit_context_specific(1)
344✔
123
      .encode(m_public_key.encode(EC_Point_Format::Uncompressed), ASN1_Type::BitString)
688✔
124
      .end_cons()
344✔
125
      .end_cons()
344✔
126
      .get_contents();
688✔
127
}
128

129
EC_PrivateKey::EC_PrivateKey(const AlgorithmIdentifier& alg_id,
1,244✔
130
                             std::span<const uint8_t> key_bits,
131
                             bool with_modular_inverse) {
1,244✔
132
   m_domain_params = EC_Group(alg_id.parameters());
1,244✔
133
   m_domain_encoding = default_encoding_for(m_domain_params);
977✔
134

135
   OID key_parameters;
915✔
136
   secure_vector<uint8_t> public_key_bits;
915✔
137

138
   BER_Decoder(key_bits)
915✔
139
      .start_sequence()
1,813✔
140
      .decode_and_check<size_t>(1, "Unknown version code for ECC key")
898✔
141
      .decode_octet_string_bigint(m_private_key)
896✔
142
      .decode_optional(key_parameters, ASN1_Type(0), ASN1_Class::ExplicitContextSpecific)
1,798✔
143
      .decode_optional_string(public_key_bits, ASN1_Type::BitString, 1, ASN1_Class::ExplicitContextSpecific)
891✔
144
      .end_cons();
886✔
145

146
   if(public_key_bits.empty()) {
885✔
147
      if(with_modular_inverse) {
377✔
148
         // ECKCDSA
149
         m_public_key = domain().get_base_point() * m_domain_params.inverse_mod_order(m_private_key);
×
150
      } else {
151
         m_public_key = domain().get_base_point() * m_private_key;
754✔
152
      }
153

154
      BOTAN_ASSERT(m_public_key.on_the_curve(), "Public point derived from loaded key was on the curve");
377✔
155
   } else {
156
      m_public_key = domain().OS2ECP(public_key_bits);
951✔
157
      // OS2ECP verifies that the point is on the curve
158
   }
159
}
1,369✔
160

161
const BigInt& EC_PublicKey::get_int_field(std::string_view field) const {
2✔
162
   if(field == "public_x") {
2✔
163
      BOTAN_ASSERT_NOMSG(this->public_point().is_affine());
×
164
      return this->public_point().get_x();
×
165
   } else if(field == "public_y") {
2✔
166
      BOTAN_ASSERT_NOMSG(this->public_point().is_affine());
×
167
      return this->public_point().get_y();
×
168
   } else if(field == "base_x") {
2✔
169
      return this->domain().get_g_x();
×
170
   } else if(field == "base_y") {
2✔
171
      return this->domain().get_g_y();
×
172
   } else if(field == "p") {
2✔
173
      return this->domain().get_p();
×
174
   } else if(field == "a") {
2✔
175
      return this->domain().get_a();
×
176
   } else if(field == "b") {
2✔
177
      return this->domain().get_b();
×
178
   } else if(field == "cofactor") {
2✔
179
      return this->domain().get_cofactor();
×
180
   } else if(field == "order") {
2✔
181
      return this->domain().get_order();
×
182
   } else {
183
      return Public_Key::get_int_field(field);
2✔
184
   }
185
}
186

187
const BigInt& EC_PrivateKey::get_int_field(std::string_view field) const {
10✔
188
   if(field == "x") {
10✔
189
      return this->private_value();
9✔
190
   } else {
191
      return EC_PublicKey::get_int_field(field);
1✔
192
   }
193
}
194

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

© 2025 Coveralls, Inc