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

randombit / botan / 5123321399

30 May 2023 04:06PM UTC coverage: 92.213% (+0.004%) from 92.209%
5123321399

Pull #3558

github

web-flow
Merge dd72f7389 into 057bcbc35
Pull Request #3558: Add braces around all if/else statements

75602 of 81986 relevant lines covered (92.21%)

11859779.3 hits per line

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

81.0
/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 { return domain().get_p_bits(); }
794✔
22

23
size_t EC_PublicKey::estimated_strength() const { return ecp_work_factor(key_length()); }
296✔
24

25
namespace {
26

27
EC_Group_Encoding default_encoding_for(EC_Group& group) {
16,185✔
28
   if(group.get_curve_oid().empty()) {
16,124✔
29
      return EC_Group_Encoding::Explicit;
30
   } else {
31
      return EC_Group_Encoding::NamedCurve;
16,095✔
32
   }
33
}
34

35
}  // namespace
36

37
EC_PublicKey::EC_PublicKey(const EC_Group& dom_par, const EC_Point& pub_point) :
12,394✔
38
      m_domain_params(dom_par), m_public_key(pub_point), m_domain_encoding(default_encoding_for(m_domain_params)) {}
24,788✔
39

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

45
bool EC_PublicKey::check_key(RandomNumberGenerator& rng, bool /*strong*/) const {
79✔
46
   return m_domain_params.verify_group(rng) && m_domain_params.verify_public_element(public_point());
79✔
47
}
48

49
AlgorithmIdentifier EC_PublicKey::algorithm_identifier() const {
700✔
50
   return AlgorithmIdentifier(object_identifier(), DER_domain());
1,400✔
51
}
52

53
std::vector<uint8_t> EC_PublicKey::public_key_bits() const { return public_point().encode(point_encoding()); }
371✔
54

55
void EC_PublicKey::set_point_encoding(EC_Point_Format enc) {
3✔
56
   if(enc != EC_Point_Format::Compressed && enc != EC_Point_Format::Uncompressed && enc != EC_Point_Format::Hybrid) {
3✔
57
      throw Invalid_Argument("Invalid point encoding for EC_PublicKey");
1✔
58
   }
59

60
   m_point_encoding = enc;
2✔
61
}
2✔
62

63
void EC_PublicKey::set_parameter_encoding(EC_Group_Encoding form) {
×
64
   if(form == EC_Group_Encoding::NamedCurve && m_domain_params.get_curve_oid().empty()) {
×
65
      throw Invalid_Argument("Cannot used NamedCurve encoding for a curve without an OID");
×
66
   }
67

68
   m_domain_encoding = form;
×
69
}
×
70

71
const BigInt& EC_PrivateKey::private_value() const {
1,211✔
72
   if(m_private_key == 0) {
1,211✔
73
      throw Invalid_State("EC_PrivateKey::private_value - uninitialized");
×
74
   }
75

76
   return m_private_key;
1,211✔
77
}
78

79
/**
80
* EC_PrivateKey constructor
81
*/
82
EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng,
1,030✔
83
                             const EC_Group& ec_group,
84
                             const BigInt& x,
85
                             bool with_modular_inverse) {
1,030✔
86
   m_domain_params = ec_group;
1,030✔
87
   m_domain_encoding = default_encoding_for(m_domain_params);
1,030✔
88

89
   if(x == 0) {
1,030✔
90
      m_private_key = ec_group.random_scalar(rng);
1,000✔
91
   } else {
92
      m_private_key = x;
530✔
93
   }
94

95
   std::vector<BigInt> ws;
1,030✔
96

97
   if(with_modular_inverse) {
1,030✔
98
      // ECKCDSA
99
      m_public_key = domain().blinded_base_point_multiply(m_domain_params.inverse_mod_order(m_private_key), rng, ws);
171✔
100
   } else {
101
      m_public_key = domain().blinded_base_point_multiply(m_private_key, rng, ws);
1,946✔
102
   }
103

104
   BOTAN_ASSERT(m_public_key.on_the_curve(), "Generated public key point was on the curve");
1,030✔
105
}
1,030✔
106

107
secure_vector<uint8_t> EC_PrivateKey::raw_private_key_bits() const { return BigInt::encode_locked(m_private_key); }
×
108

109
secure_vector<uint8_t> EC_PrivateKey::private_key_bits() const {
344✔
110
   return DER_Encoder()
344✔
111
      .start_sequence()
344✔
112
      .encode(static_cast<size_t>(1))
344✔
113
      .encode(BigInt::encode_1363(m_private_key, m_private_key.bytes()), ASN1_Type::OctetString)
1,032✔
114
      .start_explicit_context_specific(1)
344✔
115
      .encode(m_public_key.encode(EC_Point_Format::Uncompressed), ASN1_Type::BitString)
688✔
116
      .end_cons()
344✔
117
      .end_cons()
344✔
118
      .get_contents();
688✔
119
}
120

121
EC_PrivateKey::EC_PrivateKey(const AlgorithmIdentifier& alg_id,
800✔
122
                             std::span<const uint8_t> key_bits,
123
                             bool with_modular_inverse) {
800✔
124
   m_domain_params = EC_Group(alg_id.parameters());
800✔
125
   m_domain_encoding = default_encoding_for(m_domain_params);
534✔
126

127
   OID key_parameters;
473✔
128
   secure_vector<uint8_t> public_key_bits;
473✔
129

130
   BER_Decoder(key_bits)
473✔
131
      .start_sequence()
1,385✔
132
      .decode_and_check<size_t>(1, "Unknown version code for ECC key")
456✔
133
      .decode_octet_string_bigint(m_private_key)
455✔
134
      .decode_optional(key_parameters, ASN1_Type(0), ASN1_Class::ExplicitContextSpecific)
889✔
135
      .decode_optional_string(public_key_bits, ASN1_Type::BitString, 1, ASN1_Class::ExplicitContextSpecific)
423✔
136
      .end_cons();
423✔
137

138
   if(public_key_bits.empty()) {
422✔
139
      if(with_modular_inverse) {
98✔
140
         // ECKCDSA
141
         m_public_key = domain().get_base_point() * m_domain_params.inverse_mod_order(m_private_key);
×
142
      } else {
143
         m_public_key = domain().get_base_point() * m_private_key;
196✔
144
      }
145

146
      BOTAN_ASSERT(m_public_key.on_the_curve(), "Public point derived from loaded key was on the curve");
98✔
147
   } else {
148
      m_public_key = domain().OS2ECP(public_key_bits);
679✔
149
      // OS2ECP verifies that the point is on the curve
150
   }
151
}
871✔
152

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

179
const BigInt& EC_PrivateKey::get_int_field(std::string_view field) const {
10✔
180
   if(field == "x") {
10✔
181
      return this->private_value();
9✔
182
   } else {
183
      return EC_PublicKey::get_int_field(field);
1✔
184
   }
185
}
186

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