Botan 3.4.0
Crypto and TLS for C&
ec_point.cpp
Go to the documentation of this file.
1/*
2* Point arithmetic on elliptic curves over GF(p)
3*
4* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke
5* 2008-2011,2012,2014,2015,2018 Jack Lloyd
6*
7* Botan is released under the Simplified BSD License (see license.txt)
8*/
9
10#include <botan/ec_point.h>
11
12#include <botan/numthry.h>
13#include <botan/rng.h>
14#include <botan/internal/ct_utils.h>
15
16namespace Botan {
17
18EC_Point::EC_Point(const CurveGFp& curve) : m_curve(curve), m_coord_x(0), m_coord_y(curve.get_1_rep()), m_coord_z(0) {
19 // Assumes Montgomery rep of zero is zero
20}
21
22EC_Point::EC_Point(const CurveGFp& curve, const BigInt& x, const BigInt& y) :
23 m_curve(curve), m_coord_x(x), m_coord_y(y), m_coord_z(m_curve.get_1_rep()) {
24 if(x < 0 || x >= curve.get_p()) {
25 throw Invalid_Argument("Invalid EC_Point affine x");
26 }
27 if(y < 0 || y >= curve.get_p()) {
28 throw Invalid_Argument("Invalid EC_Point affine y");
29 }
30
31 secure_vector<word> monty_ws(m_curve.get_ws_size());
32 m_curve.to_rep(m_coord_x, monty_ws);
33 m_curve.to_rep(m_coord_y, monty_ws);
34}
35
40
42 const BigInt mask = BigInt::random_integer(rng, 2, m_curve.get_p());
43
44 /*
45 * No reason to convert this to Montgomery representation first,
46 * just pretend the random mask was chosen as Redc(mask) and the
47 * random mask we generated above is in the Montgomery
48 * representation.
49 * //m_curve.to_rep(mask, ws);
50 */
51 const BigInt mask2 = m_curve.sqr_to_tmp(mask, ws);
52 const BigInt mask3 = m_curve.mul_to_tmp(mask2, mask, ws);
53
54 m_coord_x = m_curve.mul_to_tmp(m_coord_x, mask2, ws);
55 m_coord_y = m_curve.mul_to_tmp(m_coord_y, mask3, ws);
56 m_coord_z = m_curve.mul_to_tmp(m_coord_z, mask, ws);
57}
58
59namespace {
60
61inline void resize_ws(std::vector<BigInt>& ws_bn, size_t cap_size) {
62 BOTAN_ASSERT(ws_bn.size() >= EC_Point::WORKSPACE_SIZE, "Expected size for EC_Point workspace");
63
64 for(auto& ws : ws_bn) {
65 if(ws.size() < cap_size) {
66 ws.get_word_vector().resize(cap_size);
67 }
68 }
69}
70
71} // namespace
72
74 const word x_words[], size_t x_size, const word y_words[], size_t y_size, std::vector<BigInt>& ws_bn) {
75 if((CT::all_zeros(x_words, x_size) & CT::all_zeros(y_words, y_size)).as_bool()) {
76 return;
77 }
78
79 if(is_zero()) {
80 m_coord_x.set_words(x_words, x_size);
81 m_coord_y.set_words(y_words, y_size);
82 m_coord_z = m_curve.get_1_rep();
83 return;
84 }
85
86 resize_ws(ws_bn, m_curve.get_ws_size());
87
88 secure_vector<word>& ws = ws_bn[0].get_word_vector();
89 secure_vector<word>& sub_ws = ws_bn[1].get_word_vector();
90
91 BigInt& T0 = ws_bn[2];
92 BigInt& T1 = ws_bn[3];
93 BigInt& T2 = ws_bn[4];
94 BigInt& T3 = ws_bn[5];
95 BigInt& T4 = ws_bn[6];
96
97 /*
98 https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-1998-cmo-2
99 simplified with Z2 = 1
100 */
101
102 const BigInt& p = m_curve.get_p();
103
104 m_curve.sqr(T3, m_coord_z, ws); // z1^2
105 m_curve.mul(T4, x_words, x_size, T3, ws); // x2*z1^2
106
107 m_curve.mul(T2, m_coord_z, T3, ws); // z1^3
108 m_curve.mul(T0, y_words, y_size, T2, ws); // y2*z1^3
109
110 T4.mod_sub(m_coord_x, p, sub_ws); // x2*z1^2 - x1*z2^2
111
112 T0.mod_sub(m_coord_y, p, sub_ws);
113
114 if(T4.is_zero()) {
115 if(T0.is_zero()) {
116 mult2(ws_bn);
117 return;
118 }
119
120 // setting to zero:
121 m_coord_x.clear();
122 m_coord_y = m_curve.get_1_rep();
123 m_coord_z.clear();
124 return;
125 }
126
127 m_curve.sqr(T2, T4, ws);
128
129 m_curve.mul(T3, m_coord_x, T2, ws);
130
131 m_curve.mul(T1, T2, T4, ws);
132
133 m_curve.sqr(m_coord_x, T0, ws);
134 m_coord_x.mod_sub(T1, p, sub_ws);
135
136 m_coord_x.mod_sub(T3, p, sub_ws);
137 m_coord_x.mod_sub(T3, p, sub_ws);
138
139 T3.mod_sub(m_coord_x, p, sub_ws);
140
141 m_curve.mul(T2, T0, T3, ws);
142 m_curve.mul(T0, m_coord_y, T1, ws);
143 T2.mod_sub(T0, p, sub_ws);
144 m_coord_y.swap(T2);
145
146 m_curve.mul(T0, m_coord_z, T4, ws);
147 m_coord_z.swap(T0);
148}
149
150void EC_Point::add(const word x_words[],
151 size_t x_size,
152 const word y_words[],
153 size_t y_size,
154 const word z_words[],
155 size_t z_size,
156 std::vector<BigInt>& ws_bn) {
157 if((CT::all_zeros(x_words, x_size) & CT::all_zeros(z_words, z_size)).as_bool()) {
158 return;
159 }
160
161 if(is_zero()) {
162 m_coord_x.set_words(x_words, x_size);
163 m_coord_y.set_words(y_words, y_size);
164 m_coord_z.set_words(z_words, z_size);
165 return;
166 }
167
168 resize_ws(ws_bn, m_curve.get_ws_size());
169
170 secure_vector<word>& ws = ws_bn[0].get_word_vector();
171 secure_vector<word>& sub_ws = ws_bn[1].get_word_vector();
172
173 BigInt& T0 = ws_bn[2];
174 BigInt& T1 = ws_bn[3];
175 BigInt& T2 = ws_bn[4];
176 BigInt& T3 = ws_bn[5];
177 BigInt& T4 = ws_bn[6];
178 BigInt& T5 = ws_bn[7];
179
180 /*
181 https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-1998-cmo-2
182 */
183
184 const BigInt& p = m_curve.get_p();
185
186 m_curve.sqr(T0, z_words, z_size, ws); // z2^2
187 m_curve.mul(T1, m_coord_x, T0, ws); // x1*z2^2
188 m_curve.mul(T3, z_words, z_size, T0, ws); // z2^3
189 m_curve.mul(T2, m_coord_y, T3, ws); // y1*z2^3
190
191 m_curve.sqr(T3, m_coord_z, ws); // z1^2
192 m_curve.mul(T4, x_words, x_size, T3, ws); // x2*z1^2
193
194 m_curve.mul(T5, m_coord_z, T3, ws); // z1^3
195 m_curve.mul(T0, y_words, y_size, T5, ws); // y2*z1^3
196
197 T4.mod_sub(T1, p, sub_ws); // x2*z1^2 - x1*z2^2
198
199 T0.mod_sub(T2, p, sub_ws);
200
201 if(T4.is_zero()) {
202 if(T0.is_zero()) {
203 mult2(ws_bn);
204 return;
205 }
206
207 // setting to zero:
208 m_coord_x.clear();
209 m_coord_y = m_curve.get_1_rep();
210 m_coord_z.clear();
211 return;
212 }
213
214 m_curve.sqr(T5, T4, ws);
215
216 m_curve.mul(T3, T1, T5, ws);
217
218 m_curve.mul(T1, T5, T4, ws);
219
220 m_curve.sqr(m_coord_x, T0, ws);
221 m_coord_x.mod_sub(T1, p, sub_ws);
222 m_coord_x.mod_sub(T3, p, sub_ws);
223 m_coord_x.mod_sub(T3, p, sub_ws);
224
225 T3.mod_sub(m_coord_x, p, sub_ws);
226
227 m_curve.mul(m_coord_y, T0, T3, ws);
228 m_curve.mul(T3, T2, T1, ws);
229
230 m_coord_y.mod_sub(T3, p, sub_ws);
231
232 m_curve.mul(T3, z_words, z_size, m_coord_z, ws);
233 m_curve.mul(m_coord_z, T3, T4, ws);
234}
235
236void EC_Point::mult2i(size_t iterations, std::vector<BigInt>& ws_bn) {
237 if(iterations == 0) {
238 return;
239 }
240
241 if(m_coord_y.is_zero()) {
242 *this = EC_Point(m_curve); // setting myself to zero
243 return;
244 }
245
246 /*
247 TODO we can save 2 squarings per iteration by computing
248 a*Z^4 using values cached from previous iteration
249 */
250 for(size_t i = 0; i != iterations; ++i) {
251 mult2(ws_bn);
252 }
253}
254
255// *this *= 2
256void EC_Point::mult2(std::vector<BigInt>& ws_bn) {
257 if(is_zero()) {
258 return;
259 }
260
261 if(m_coord_y.is_zero()) {
262 *this = EC_Point(m_curve); // setting myself to zero
263 return;
264 }
265
266 resize_ws(ws_bn, m_curve.get_ws_size());
267
268 secure_vector<word>& ws = ws_bn[0].get_word_vector();
269 secure_vector<word>& sub_ws = ws_bn[1].get_word_vector();
270
271 BigInt& T0 = ws_bn[2];
272 BigInt& T1 = ws_bn[3];
273 BigInt& T2 = ws_bn[4];
274 BigInt& T3 = ws_bn[5];
275 BigInt& T4 = ws_bn[6];
276
277 /*
278 https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-1986-cc
279 */
280 const BigInt& p = m_curve.get_p();
281
282 m_curve.sqr(T0, m_coord_y, ws);
283
284 m_curve.mul(T1, m_coord_x, T0, ws);
285 T1.mod_mul(4, p, sub_ws);
286
287 if(m_curve.a_is_zero()) {
288 // if a == 0 then 3*x^2 + a*z^4 is just 3*x^2
289 m_curve.sqr(T4, m_coord_x, ws); // x^2
290 T4.mod_mul(3, p, sub_ws); // 3*x^2
291 } else if(m_curve.a_is_minus_3()) {
292 /*
293 if a == -3 then
294 3*x^2 + a*z^4 == 3*x^2 - 3*z^4 == 3*(x^2-z^4) == 3*(x-z^2)*(x+z^2)
295 */
296 m_curve.sqr(T3, m_coord_z, ws); // z^2
297
298 // (x-z^2)
299 T2 = m_coord_x;
300 T2.mod_sub(T3, p, sub_ws);
301
302 // (x+z^2)
303 T3.mod_add(m_coord_x, p, sub_ws);
304
305 m_curve.mul(T4, T2, T3, ws); // (x-z^2)*(x+z^2)
306
307 T4.mod_mul(3, p, sub_ws); // 3*(x-z^2)*(x+z^2)
308 } else {
309 m_curve.sqr(T3, m_coord_z, ws); // z^2
310 m_curve.sqr(T4, T3, ws); // z^4
311 m_curve.mul(T3, m_curve.get_a_rep(), T4, ws); // a*z^4
312
313 m_curve.sqr(T4, m_coord_x, ws); // x^2
314 T4.mod_mul(3, p, sub_ws);
315 T4.mod_add(T3, p, sub_ws); // 3*x^2 + a*z^4
316 }
317
318 m_curve.sqr(T2, T4, ws);
319 T2.mod_sub(T1, p, sub_ws);
320 T2.mod_sub(T1, p, sub_ws);
321
322 m_curve.sqr(T3, T0, ws);
323 T3.mod_mul(8, p, sub_ws);
324
325 T1.mod_sub(T2, p, sub_ws);
326
327 m_curve.mul(T0, T4, T1, ws);
328 T0.mod_sub(T3, p, sub_ws);
329
330 m_coord_x.swap(T2);
331
332 m_curve.mul(T2, m_coord_y, m_coord_z, ws);
333 T2.mod_mul(2, p, sub_ws);
334
335 m_coord_y.swap(T0);
336 m_coord_z.swap(T2);
337}
338
339// arithmetic operators
341 std::vector<BigInt> ws(EC_Point::WORKSPACE_SIZE);
342 add(rhs, ws);
343 return *this;
344}
345
347 EC_Point minus_rhs = EC_Point(rhs).negate();
348
349 if(is_zero()) {
350 *this = minus_rhs;
351 } else {
352 *this += minus_rhs;
353 }
354
355 return *this;
356}
357
359 *this = scalar * *this;
360 return *this;
361}
362
363EC_Point operator*(const BigInt& scalar, const EC_Point& point) {
365
366 const size_t scalar_bits = scalar.bits();
367
368 std::vector<BigInt> ws(EC_Point::WORKSPACE_SIZE);
369
370 EC_Point R[2] = {point.zero(), point};
371
372 for(size_t i = scalar_bits; i > 0; i--) {
373 const size_t b = scalar.get_bit(i - 1);
374 R[b ^ 1].add(R[b], ws);
375 R[b].mult2(ws);
376 }
377
378 if(scalar.is_negative()) {
379 R[0].negate();
380 }
381
382 BOTAN_DEBUG_ASSERT(R[0].on_the_curve());
383
384 return R[0];
385}
386
387//static
388void EC_Point::force_all_affine(std::vector<EC_Point>& points, secure_vector<word>& ws) {
389 if(points.size() <= 1) {
390 for(auto& point : points) {
391 point.force_affine();
392 }
393 return;
394 }
395
396 for(auto& point : points) {
397 if(point.is_zero()) {
398 throw Invalid_State("Cannot convert zero ECC point to affine");
399 }
400 }
401
402 /*
403 For >= 2 points use Montgomery's trick
404
405 See Algorithm 2.26 in "Guide to Elliptic Curve Cryptography"
406 (Hankerson, Menezes, Vanstone)
407
408 TODO is it really necessary to save all k points in c?
409 */
410
411 const CurveGFp& curve = points[0].m_curve;
412 const BigInt& rep_1 = curve.get_1_rep();
413
414 if(ws.size() < curve.get_ws_size()) {
415 ws.resize(curve.get_ws_size());
416 }
417
418 std::vector<BigInt> c(points.size());
419 c[0] = points[0].m_coord_z;
420
421 for(size_t i = 1; i != points.size(); ++i) {
422 curve.mul(c[i], c[i - 1], points[i].m_coord_z, ws);
423 }
424
425 BigInt s_inv = curve.invert_element(c[c.size() - 1], ws);
426
427 BigInt z_inv, z2_inv, z3_inv;
428
429 for(size_t i = points.size() - 1; i != 0; i--) {
430 EC_Point& point = points[i];
431
432 curve.mul(z_inv, s_inv, c[i - 1], ws);
433
434 s_inv = curve.mul_to_tmp(s_inv, point.m_coord_z, ws);
435
436 curve.sqr(z2_inv, z_inv, ws);
437 curve.mul(z3_inv, z2_inv, z_inv, ws);
438 point.m_coord_x = curve.mul_to_tmp(point.m_coord_x, z2_inv, ws);
439 point.m_coord_y = curve.mul_to_tmp(point.m_coord_y, z3_inv, ws);
440 point.m_coord_z = rep_1;
441 }
442
443 curve.sqr(z2_inv, s_inv, ws);
444 curve.mul(z3_inv, z2_inv, s_inv, ws);
445 points[0].m_coord_x = curve.mul_to_tmp(points[0].m_coord_x, z2_inv, ws);
446 points[0].m_coord_y = curve.mul_to_tmp(points[0].m_coord_y, z3_inv, ws);
447 points[0].m_coord_z = rep_1;
448}
449
451 if(is_zero()) {
452 throw Invalid_State("Cannot convert zero ECC point to affine");
453 }
454
456
457 const BigInt z_inv = m_curve.invert_element(m_coord_z, ws);
458 const BigInt z2_inv = m_curve.sqr_to_tmp(z_inv, ws);
459 const BigInt z3_inv = m_curve.mul_to_tmp(z_inv, z2_inv, ws);
460 m_coord_x = m_curve.mul_to_tmp(m_coord_x, z2_inv, ws);
461 m_coord_y = m_curve.mul_to_tmp(m_coord_y, z3_inv, ws);
462 m_coord_z = m_curve.get_1_rep();
463}
464
466 return m_curve.is_one(m_coord_z);
467}
468
470 if(is_zero()) {
471 throw Invalid_State("Cannot convert zero point to affine");
472 }
473
474 secure_vector<word> monty_ws;
475
476 if(is_affine()) {
477 return m_curve.from_rep_to_tmp(m_coord_x, monty_ws);
478 }
479
480 BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws);
481 z2 = m_curve.invert_element(z2, monty_ws);
482
483 BigInt r;
484 m_curve.mul(r, m_coord_x, z2, monty_ws);
485 m_curve.from_rep(r, monty_ws);
486 return r;
487}
488
490 if(is_zero()) {
491 throw Invalid_State("Cannot convert zero point to affine");
492 }
493
494 secure_vector<word> monty_ws;
495
496 if(is_affine()) {
497 return m_curve.from_rep_to_tmp(m_coord_y, monty_ws);
498 }
499
500 const BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws);
501 const BigInt z3 = m_curve.mul_to_tmp(m_coord_z, z2, monty_ws);
502 const BigInt z3_inv = m_curve.invert_element(z3, monty_ws);
503
504 BigInt r;
505 m_curve.mul(r, m_coord_y, z3_inv, monty_ws);
506 m_curve.from_rep(r, monty_ws);
507 return r;
508}
509
511 /*
512 Is the point still on the curve?? (If everything is correct, the
513 point is always on its curve; then the function will return true.
514 If somehow the state is corrupted, which suggests a fault attack
515 (or internal computational error), then return false.
516 */
517 if(is_zero()) {
518 return true;
519 }
520
521 secure_vector<word> monty_ws;
522
523 const BigInt y2 = m_curve.from_rep_to_tmp(m_curve.sqr_to_tmp(m_coord_y, monty_ws), monty_ws);
524 const BigInt x3 = m_curve.mul_to_tmp(m_coord_x, m_curve.sqr_to_tmp(m_coord_x, monty_ws), monty_ws);
525 const BigInt ax = m_curve.mul_to_tmp(m_coord_x, m_curve.get_a_rep(), monty_ws);
526 const BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws);
527
528 if(m_coord_z == z2) // Is z equal to 1 (in Montgomery form)?
529 {
530 if(y2 != m_curve.from_rep_to_tmp(x3 + ax + m_curve.get_b_rep(), monty_ws)) {
531 return false;
532 }
533 }
534
535 const BigInt z3 = m_curve.mul_to_tmp(m_coord_z, z2, monty_ws);
536 const BigInt ax_z4 = m_curve.mul_to_tmp(ax, m_curve.sqr_to_tmp(z2, monty_ws), monty_ws);
537 const BigInt b_z6 = m_curve.mul_to_tmp(m_curve.get_b_rep(), m_curve.sqr_to_tmp(z3, monty_ws), monty_ws);
538
539 if(y2 != m_curve.from_rep_to_tmp(x3 + ax_z4 + b_z6, monty_ws)) {
540 return false;
541 }
542
543 return true;
544}
545
546// swaps the states of *this and other, does not throw!
548 m_curve.swap(other.m_curve);
549 m_coord_x.swap(other.m_coord_x);
550 m_coord_y.swap(other.m_coord_y);
551 m_coord_z.swap(other.m_coord_z);
552}
553
554bool EC_Point::operator==(const EC_Point& other) const {
555 if(m_curve != other.m_curve) {
556 return false;
557 }
558
559 // If this is zero, only equal if other is also zero
560 if(is_zero()) {
561 return other.is_zero();
562 }
563
564 return (get_affine_x() == other.get_affine_x() && get_affine_y() == other.get_affine_y());
565}
566
567// encoding and decoding
568std::vector<uint8_t> EC_Point::encode(EC_Point_Format format) const {
569 if(is_zero()) {
570 return std::vector<uint8_t>(1); // single 0 byte
571 }
572
573 const size_t p_bytes = m_curve.get_p().bytes();
574
575 const BigInt x = get_affine_x();
576 const BigInt y = get_affine_y();
577
578 std::vector<uint8_t> result;
579
580 if(format == EC_Point_Format::Uncompressed) {
581 result.resize(1 + 2 * p_bytes);
582 result[0] = 0x04;
583 BigInt::encode_1363(&result[1], p_bytes, x);
584 BigInt::encode_1363(&result[1 + p_bytes], p_bytes, y);
585 } else if(format == EC_Point_Format::Compressed) {
586 result.resize(1 + p_bytes);
587 result[0] = 0x02 | static_cast<uint8_t>(y.get_bit(0));
588 BigInt::encode_1363(&result[1], p_bytes, x);
589 } else if(format == EC_Point_Format::Hybrid) {
590 result.resize(1 + 2 * p_bytes);
591 result[0] = 0x06 | static_cast<uint8_t>(y.get_bit(0));
592 BigInt::encode_1363(&result[1], p_bytes, x);
593 BigInt::encode_1363(&result[1 + p_bytes], p_bytes, y);
594 } else {
595 throw Invalid_Argument("EC2OSP illegal point encoding");
596 }
597
598 return result;
599}
600
601namespace {
602
603BigInt decompress_point(
604 bool yMod2, const BigInt& x, const BigInt& curve_p, const BigInt& curve_a, const BigInt& curve_b) {
605 BigInt xpow3 = x * x * x;
606
607 BigInt g = curve_a * x;
608 g += xpow3;
609 g += curve_b;
610 g = g % curve_p;
611
612 BigInt z = sqrt_modulo_prime(g, curve_p);
613
614 if(z < 0) {
615 throw Decoding_Error("Error during EC point decompression");
616 }
617
618 if(z.get_bit(0) != yMod2) {
619 z = curve_p - z;
620 }
621
622 return z;
623}
624
625} // namespace
626
627EC_Point OS2ECP(const uint8_t data[], size_t data_len, const CurveGFp& curve) {
628 // Should we really be doing this?
629 if(data_len <= 1) {
630 return EC_Point(curve); // return zero
631 }
632
633 std::pair<BigInt, BigInt> xy = OS2ECP(data, data_len, curve.get_p(), curve.get_a(), curve.get_b());
634
635 EC_Point point(curve, xy.first, xy.second);
636
637 if(!point.on_the_curve()) {
638 throw Decoding_Error("OS2ECP: Decoded point was not on the curve");
639 }
640
641 return point;
642}
643
644std::pair<BigInt, BigInt> OS2ECP(
645 const uint8_t data[], size_t data_len, const BigInt& curve_p, const BigInt& curve_a, const BigInt& curve_b) {
646 if(data_len <= 1) {
647 throw Decoding_Error("OS2ECP invalid point");
648 }
649
650 const uint8_t pc = data[0];
651
652 BigInt x, y;
653
654 if(pc == 2 || pc == 3) {
655 //compressed form
656 x = BigInt::decode(&data[1], data_len - 1);
657
658 const bool y_mod_2 = ((pc & 0x01) == 1);
659 y = decompress_point(y_mod_2, x, curve_p, curve_a, curve_b);
660 } else if(pc == 4) {
661 const size_t l = (data_len - 1) / 2;
662
663 // uncompressed form
664 x = BigInt::decode(&data[1], l);
665 y = BigInt::decode(&data[l + 1], l);
666 } else if(pc == 6 || pc == 7) {
667 const size_t l = (data_len - 1) / 2;
668
669 // hybrid form
670 x = BigInt::decode(&data[1], l);
671 y = BigInt::decode(&data[l + 1], l);
672
673 const bool y_mod_2 = ((pc & 0x01) == 1);
674
675 if(decompress_point(y_mod_2, x, curve_p, curve_a, curve_b) != y) {
676 throw Decoding_Error("OS2ECP: Decoding error in hybrid format");
677 }
678 } else {
679 throw Invalid_Argument("OS2ECP: Unknown format type " + std::to_string(pc));
680 }
681
682 return std::make_pair(x, y);
683}
684
685} // namespace Botan
#define BOTAN_DEBUG_ASSERT(expr)
Definition assert.h:98
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:50
BigInt & mod_mul(uint8_t y, const BigInt &mod, secure_vector< word > &ws)
Definition big_ops2.cpp:119
void swap(BigInt &other)
Definition bigint.h:170
static BigInt decode(const uint8_t buf[], size_t length)
Definition bigint.h:773
static BigInt random_integer(RandomNumberGenerator &rng, const BigInt &min, const BigInt &max)
Definition big_rand.cpp:43
void resize(size_t s)
Definition bigint.h:633
void set_words(const word w[], size_t len)
Definition bigint.h:522
BigInt & mod_add(const BigInt &y, const BigInt &mod, secure_vector< word > &ws)
Definition big_ops2.cpp:45
BigInt & mod_sub(const BigInt &y, const BigInt &mod, secure_vector< word > &ws)
Definition big_ops2.cpp:90
size_t bits() const
Definition bigint.cpp:290
void clear()
Definition bigint.h:370
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition big_code.cpp:105
bool is_zero() const
Definition bigint.h:428
bool is_negative() const
Definition bigint.h:528
size_t bytes() const
Definition bigint.cpp:277
bool get_bit(size_t n) const
Definition bigint.h:467
bool a_is_minus_3() const
Definition curve_gfp.h:130
void mul(BigInt &z, const BigInt &x, const BigInt &y, secure_vector< word > &ws) const
Definition curve_gfp.h:150
size_t get_ws_size() const
Definition curve_gfp.h:122
BigInt invert_element(const BigInt &x, secure_vector< word > &ws) const
Definition curve_gfp.h:136
const BigInt & get_1_rep() const
Definition curve_gfp.h:128
const BigInt & get_b_rep() const
Definition curve_gfp.h:126
bool is_one(const BigInt &x) const
Definition curve_gfp.h:134
void sqr(BigInt &z, const BigInt &x, secure_vector< word > &ws) const
Definition curve_gfp.h:158
void swap(CurveGFp &other)
Definition curve_gfp.h:180
const BigInt & get_a_rep() const
Definition curve_gfp.h:124
bool a_is_zero() const
Definition curve_gfp.h:132
BigInt from_rep_to_tmp(const BigInt &x, secure_vector< word > &ws) const
Definition curve_gfp.h:142
const BigInt & get_a() const
Definition curve_gfp.h:107
void to_rep(BigInt &x, secure_vector< word > &ws) const
Definition curve_gfp.h:138
const BigInt & get_p() const
Definition curve_gfp.h:118
BigInt sqr_to_tmp(const BigInt &x, secure_vector< word > &ws) const
Definition curve_gfp.h:174
const BigInt & get_b() const
Definition curve_gfp.h:112
void from_rep(BigInt &x, secure_vector< word > &ws) const
Definition curve_gfp.h:140
BigInt mul_to_tmp(const BigInt &x, const BigInt &y, secure_vector< word > &ws) const
Definition curve_gfp.h:168
EC_Point & negate()
Definition ec_point.h:116
void randomize_repr(RandomNumberGenerator &rng)
Definition ec_point.cpp:36
BigInt get_affine_x() const
Definition ec_point.cpp:469
void add(const EC_Point &other, std::vector< BigInt > &workspace)
Definition ec_point.h:217
void add_affine(const EC_Point &other, std::vector< BigInt > &workspace)
Definition ec_point.h:255
void mult2(std::vector< BigInt > &workspace)
Definition ec_point.cpp:256
void mult2i(size_t i, std::vector< BigInt > &workspace)
Definition ec_point.cpp:236
EC_Point & operator-=(const EC_Point &rhs)
Definition ec_point.cpp:346
bool is_zero() const
Definition ec_point.h:178
bool on_the_curve() const
Definition ec_point.cpp:510
EC_Point & operator+=(const EC_Point &rhs)
Definition ec_point.cpp:340
EC_Point zero() const
Definition ec_point.h:318
bool is_affine() const
Definition ec_point.cpp:465
bool operator==(const EC_Point &other) const
Definition ec_point.cpp:554
void force_affine()
Definition ec_point.cpp:450
BigInt get_affine_y() const
Definition ec_point.cpp:489
EC_Point & operator*=(const BigInt &scalar)
Definition ec_point.cpp:358
friend void swap(EC_Point &x, EC_Point &y)
Definition ec_point.h:193
EC_Point()=default
static void force_all_affine(std::vector< EC_Point > &points, secure_vector< word > &ws)
Definition ec_point.cpp:388
std::vector< uint8_t > encode(EC_Point_Format format) const
Definition ec_point.cpp:568
constexpr CT::Mask< T > all_zeros(const T elem[], size_t len)
Definition ct_utils.h:332
BigInt operator*(const BigInt &x, const BigInt &y)
Definition big_ops3.cpp:46
EC_Point_Format
Definition ec_point.h:19
EC_Point OS2ECP(const uint8_t data[], size_t data_len, const CurveGFp &curve)
Definition ec_point.cpp:627
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
BigInt sqrt_modulo_prime(const BigInt &a, const BigInt &p)
Definition numthry.cpp:26