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

randombit / botan / 13191750282

07 Feb 2025 02:08AM UTC coverage: 91.276% (+0.001%) from 91.275%
13191750282

Pull #4555

github

web-flow
Merge f39fdedd9 into d4d48503e
Pull Request #4555: Remove the workspace argument to various ECC interfaces

94429 of 103454 relevant lines covered (91.28%)

11206783.99 hits per line

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

95.42
/src/lib/pubkey/ec_group/ec_inner_pc.cpp
1
/*
2
* (C) 2024 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include <botan/internal/ec_inner_pc.h>
8

9
namespace Botan {
10

11
const EC_Scalar_Data_PC& EC_Scalar_Data_PC::checked_ref(const EC_Scalar_Data& data) {
159,559✔
12
   const auto* p = dynamic_cast<const EC_Scalar_Data_PC*>(&data);
159,559✔
13
   if(!p) {
159,559✔
14
      throw Invalid_State("Failed conversion to EC_Scalar_Data_PC");
×
15
   }
16
   return *p;
159,559✔
17
}
18

19
const std::shared_ptr<const EC_Group_Data>& EC_Scalar_Data_PC::group() const {
105,019✔
20
   return m_group;
41,908✔
21
}
22

23
size_t EC_Scalar_Data_PC::bytes() const {
47,337✔
24
   return this->group()->order_bytes();
47,337✔
25
}
26

27
std::unique_ptr<EC_Scalar_Data> EC_Scalar_Data_PC::clone() const {
41,908✔
28
   return std::make_unique<EC_Scalar_Data_PC>(this->group(), this->value());
41,908✔
29
}
30

31
bool EC_Scalar_Data_PC::is_zero() const {
39,701✔
32
   auto& pcurve = this->group()->pcurve();
39,701✔
33
   return pcurve.scalar_is_zero(m_v);
39,701✔
34
}
35

36
bool EC_Scalar_Data_PC::is_eq(const EC_Scalar_Data& other) const {
1,670✔
37
   auto& pcurve = group()->pcurve();
1,670✔
38
   return pcurve.scalar_equal(m_v, checked_ref(other).m_v);
1,670✔
39
}
40

41
void EC_Scalar_Data_PC::assign(const EC_Scalar_Data& other) {
×
42
   m_v = checked_ref(other).value();
×
43
}
×
44

45
void EC_Scalar_Data_PC::square_self() {
3,196✔
46
   // TODO square in place
47
   m_v = m_group->pcurve().scalar_square(m_v);
3,196✔
48
}
3,196✔
49

50
std::unique_ptr<EC_Scalar_Data> EC_Scalar_Data_PC::negate() const {
7,425✔
51
   return std::make_unique<EC_Scalar_Data_PC>(m_group, m_group->pcurve().scalar_negate(m_v));
7,425✔
52
}
53

54
std::unique_ptr<EC_Scalar_Data> EC_Scalar_Data_PC::invert() const {
6,948✔
55
   return std::make_unique<EC_Scalar_Data_PC>(m_group, m_group->pcurve().scalar_invert(m_v));
6,948✔
56
}
57

58
std::unique_ptr<EC_Scalar_Data> EC_Scalar_Data_PC::invert_vartime() const {
19,233✔
59
   return std::make_unique<EC_Scalar_Data_PC>(m_group, m_group->pcurve().scalar_invert_vartime(m_v));
19,233✔
60
}
61

62
std::unique_ptr<EC_Scalar_Data> EC_Scalar_Data_PC::add(const EC_Scalar_Data& other) const {
8,473✔
63
   return std::make_unique<EC_Scalar_Data_PC>(m_group, group()->pcurve().scalar_add(m_v, checked_ref(other).m_v));
8,473✔
64
}
65

66
std::unique_ptr<EC_Scalar_Data> EC_Scalar_Data_PC::sub(const EC_Scalar_Data& other) const {
6,487✔
67
   return std::make_unique<EC_Scalar_Data_PC>(m_group, group()->pcurve().scalar_sub(m_v, checked_ref(other).m_v));
6,487✔
68
}
69

70
std::unique_ptr<EC_Scalar_Data> EC_Scalar_Data_PC::mul(const EC_Scalar_Data& other) const {
60,296✔
71
   return std::make_unique<EC_Scalar_Data_PC>(m_group, group()->pcurve().scalar_mul(m_v, checked_ref(other).m_v));
60,296✔
72
}
73

74
void EC_Scalar_Data_PC::serialize_to(std::span<uint8_t> bytes) const {
48,204✔
75
   BOTAN_ARG_CHECK(bytes.size() == m_group->order_bytes(), "Invalid output length");
48,204✔
76
   m_group->pcurve().serialize_scalar(bytes, m_v);
48,204✔
77
}
48,204✔
78

79
EC_AffinePoint_Data_PC::EC_AffinePoint_Data_PC(std::shared_ptr<const EC_Group_Data> group,
71,654✔
80
                                               PCurve::PrimeOrderCurve::AffinePoint pt) :
71,654✔
81
      m_group(std::move(group)), m_pt(std::move(pt)) {
71,654✔
82
   auto& pcurve = m_group->pcurve();
71,654✔
83

84
   if(!pcurve.affine_point_is_identity(m_pt)) {
71,654✔
85
      m_xy.resize(1 + 2 * field_element_bytes());
71,438✔
86
      pcurve.serialize_point(m_xy, m_pt);
71,438✔
87
   }
88
}
71,654✔
89

90
const EC_AffinePoint_Data_PC& EC_AffinePoint_Data_PC::checked_ref(const EC_AffinePoint_Data& data) {
32,792✔
91
   const auto* p = dynamic_cast<const EC_AffinePoint_Data_PC*>(&data);
32,792✔
92
   if(!p) {
32,792✔
93
      throw Invalid_State("Failed conversion to EC_AffinePoint_Data_PC");
×
94
   }
95
   return *p;
32,792✔
96
}
97

98
std::unique_ptr<EC_AffinePoint_Data> EC_AffinePoint_Data_PC::clone() const {
11,700✔
99
   return std::make_unique<EC_AffinePoint_Data_PC>(m_group, m_pt);
11,700✔
100
}
101

102
const std::shared_ptr<const EC_Group_Data>& EC_AffinePoint_Data_PC::group() const {
49,606✔
103
   return m_group;
49,606✔
104
}
105

106
std::unique_ptr<EC_AffinePoint_Data> EC_AffinePoint_Data_PC::mul(const EC_Scalar_Data& scalar,
10,021✔
107
                                                                 RandomNumberGenerator& rng) const {
108
   BOTAN_ARG_CHECK(scalar.group() == m_group, "Curve mismatch");
10,021✔
109
   const auto& k = EC_Scalar_Data_PC::checked_ref(scalar).value();
10,021✔
110
   auto& pcurve = m_group->pcurve();
10,021✔
111
   auto pt = pcurve.point_to_affine(pcurve.mul(m_pt, k, rng));
10,021✔
112
   return std::make_unique<EC_AffinePoint_Data_PC>(m_group, std::move(pt));
10,021✔
113
}
10,021✔
114

115
secure_vector<uint8_t> EC_AffinePoint_Data_PC::mul_x_only(const EC_Scalar_Data& scalar,
2,653✔
116
                                                          RandomNumberGenerator& rng) const {
117
   BOTAN_ARG_CHECK(scalar.group() == m_group, "Curve mismatch");
2,653✔
118
   const auto& k = EC_Scalar_Data_PC::checked_ref(scalar).value();
2,653✔
119
   return m_group->pcurve().mul_x_only(m_pt, k, rng);
2,653✔
120
}
121

122
size_t EC_AffinePoint_Data_PC::field_element_bytes() const {
149,585✔
123
   return m_group->pcurve().field_element_bytes();
149,585✔
124
}
125

126
bool EC_AffinePoint_Data_PC::is_identity() const {
80,523✔
127
   return m_xy.empty();
80,523✔
128
}
129

130
void EC_AffinePoint_Data_PC::serialize_x_to(std::span<uint8_t> bytes) const {
8,630✔
131
   BOTAN_STATE_CHECK(!this->is_identity());
8,630✔
132
   const size_t fe_bytes = this->field_element_bytes();
8,630✔
133
   BOTAN_ARG_CHECK(bytes.size() == fe_bytes, "Invalid output size");
8,630✔
134
   copy_mem(bytes, std::span{m_xy}.subspan(1, fe_bytes));
8,630✔
135
}
8,630✔
136

137
void EC_AffinePoint_Data_PC::serialize_y_to(std::span<uint8_t> bytes) const {
20✔
138
   BOTAN_STATE_CHECK(!this->is_identity());
20✔
139
   const size_t fe_bytes = this->field_element_bytes();
20✔
140
   BOTAN_ARG_CHECK(bytes.size() == fe_bytes, "Invalid output size");
20✔
141
   copy_mem(bytes, std::span{m_xy}.subspan(1 + fe_bytes, fe_bytes));
20✔
142
}
20✔
143

144
void EC_AffinePoint_Data_PC::serialize_xy_to(std::span<uint8_t> bytes) const {
150✔
145
   BOTAN_STATE_CHECK(!this->is_identity());
150✔
146
   const size_t fe_bytes = this->field_element_bytes();
150✔
147
   BOTAN_ARG_CHECK(bytes.size() == 2 * fe_bytes, "Invalid output size");
150✔
148
   copy_mem(bytes, std::span{m_xy}.last(2 * fe_bytes));
150✔
149
}
150✔
150

151
void EC_AffinePoint_Data_PC::serialize_compressed_to(std::span<uint8_t> bytes) const {
8,206✔
152
   BOTAN_STATE_CHECK(!this->is_identity());
8,206✔
153
   const size_t fe_bytes = this->field_element_bytes();
8,206✔
154
   BOTAN_ARG_CHECK(bytes.size() == 1 + fe_bytes, "Invalid output size");
8,206✔
155
   const bool y_is_odd = (m_xy.back() & 0x01) == 0x01;
8,206✔
156

157
   BufferStuffer stuffer(bytes);
8,206✔
158
   stuffer.append(y_is_odd ? 0x03 : 0x02);
12,424✔
159
   this->serialize_x_to(stuffer.next(fe_bytes));
8,206✔
160
}
8,206✔
161

162
void EC_AffinePoint_Data_PC::serialize_uncompressed_to(std::span<uint8_t> bytes) const {
15,291✔
163
   BOTAN_STATE_CHECK(!this->is_identity());
15,291✔
164
   const size_t fe_bytes = this->field_element_bytes();
15,291✔
165
   BOTAN_ARG_CHECK(bytes.size() == 1 + 2 * fe_bytes, "Invalid output size");
15,291✔
166
   copy_mem(bytes, m_xy);
15,291✔
167
}
15,291✔
168

169
#if defined(BOTAN_HAS_LEGACY_EC_POINT)
170
EC_Point EC_AffinePoint_Data_PC::to_legacy_point() const {
21,869✔
171
   if(this->is_identity()) {
21,869✔
172
      return EC_Point(m_group->curve());
96✔
173
   } else {
174
      const size_t fe_bytes = this->field_element_bytes();
21,773✔
175
      return EC_Point(m_group->curve(),
21,773✔
176
                      BigInt::from_bytes(std::span{m_xy}.subspan(1, fe_bytes)),
43,546✔
177
                      BigInt::from_bytes(std::span{m_xy}.last(fe_bytes)));
65,319✔
178
   }
179
}
180
#endif
181

182
EC_Mul2Table_Data_PC::EC_Mul2Table_Data_PC(const EC_AffinePoint_Data& q) : m_group(q.group()) {
11,180✔
183
   BOTAN_ARG_CHECK(q.group() == m_group, "Curve mismatch");
11,180✔
184

185
   const auto& pt_q = EC_AffinePoint_Data_PC::checked_ref(q);
11,180✔
186

187
   m_tbl = m_group->pcurve().mul2_setup_g(pt_q.value());
11,180✔
188
}
11,180✔
189

190
std::unique_ptr<EC_AffinePoint_Data> EC_Mul2Table_Data_PC::mul2_vartime(const EC_Scalar_Data& xd,
1,102✔
191
                                                                        const EC_Scalar_Data& yd) const {
192
   BOTAN_ARG_CHECK(xd.group() == m_group && yd.group() == m_group, "Curve mismatch");
1,102✔
193

194
   const auto& x = EC_Scalar_Data_PC::checked_ref(xd);
1,102✔
195
   const auto& y = EC_Scalar_Data_PC::checked_ref(yd);
1,102✔
196

197
   auto& pcurve = m_group->pcurve();
1,102✔
198

199
   if(auto pt = pcurve.mul2_vartime(*m_tbl, x.value(), y.value())) {
1,102✔
200
      return std::make_unique<EC_AffinePoint_Data_PC>(m_group, pcurve.point_to_affine(*pt));
1,102✔
201
   } else {
202
      return nullptr;
×
203
   }
1,102✔
204
}
205

206
bool EC_Mul2Table_Data_PC::mul2_vartime_x_mod_order_eq(const EC_Scalar_Data& vd,
17,624✔
207
                                                       const EC_Scalar_Data& xd,
208
                                                       const EC_Scalar_Data& yd) const {
209
   BOTAN_ARG_CHECK(xd.group() == m_group && yd.group() == m_group, "Curve mismatch");
17,624✔
210

211
   const auto& v = EC_Scalar_Data_PC::checked_ref(vd);
17,624✔
212
   const auto& x = EC_Scalar_Data_PC::checked_ref(xd);
17,624✔
213
   const auto& y = EC_Scalar_Data_PC::checked_ref(yd);
17,624✔
214

215
   return m_group->pcurve().mul2_vartime_x_mod_order_eq(*m_tbl, v.value(), x.value(), y.value());
17,624✔
216
}
217

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