Botan 3.5.0
Crypto and TLS for C&
Botan::EC_Point Class Referencefinal

#include <ec_point.h>

Public Types

enum  { WORKSPACE_SIZE = 8 }
 
typedef EC_Point_Format Compression_Type
 

Public Member Functions

void add (const EC_Point &other, std::vector< BigInt > &workspace)
 
void add (const word x_words[], size_t x_size, const word y_words[], size_t y_size, const word z_words[], size_t z_size, std::vector< BigInt > &workspace)
 
void add_affine (const EC_Point &other, std::vector< BigInt > &workspace)
 
void add_affine (const word x_words[], size_t x_size, const word y_words[], size_t y_size, std::vector< BigInt > &workspace)
 
EC_Point double_of (std::vector< BigInt > &workspace) const
 
 EC_Point ()=default
 
 EC_Point (const CurveGFp &curve)
 
 EC_Point (const CurveGFp &curve, const BigInt &x, const BigInt &y)
 
 EC_Point (const EC_Point &)=default
 
 EC_Point (EC_Point &&other)
 
std::vector< uint8_t > encode (EC_Point_Format format) const
 
void force_affine ()
 
BigInt get_affine_x () const
 
BigInt get_affine_y () const
 
const CurveGFpget_curve () const
 
const BigIntget_x () const
 
const BigIntget_y () const
 
const BigIntget_z () const
 
bool is_affine () const
 
bool is_zero () const
 
EC_Point mul (const BigInt &scalar) const
 
void mult2 (std::vector< BigInt > &workspace)
 
void mult2i (size_t i, std::vector< BigInt > &workspace)
 
EC_Pointnegate ()
 
bool on_the_curve () const
 
bool operator!= (const EC_Point &other) const =default
 
EC_Pointoperator*= (const BigInt &scalar)
 
EC_Pointoperator+= (const EC_Point &rhs)
 
EC_Pointoperator-= (const EC_Point &rhs)
 
EC_Pointoperator= (const EC_Point &)=default
 
EC_Pointoperator= (EC_Point &&other)
 
bool operator== (const EC_Point &other) const
 
EC_Point plus (const EC_Point &other, std::vector< BigInt > &workspace) const
 
void randomize_repr (RandomNumberGenerator &rng)
 
void randomize_repr (RandomNumberGenerator &rng, secure_vector< word > &ws)
 
void swap (EC_Point &other) noexcept
 
void swap_coords (BigInt &new_x, BigInt &new_y, BigInt &new_z)
 
secure_vector< uint8_t > x_bytes () const
 
secure_vector< uint8_t > xy_bytes () const
 
secure_vector< uint8_t > y_bytes () const
 
EC_Point zero () const
 

Static Public Member Functions

static void force_all_affine (std::span< EC_Point > points, secure_vector< word > &ws)
 

Friends

class EC_Point_Base_Point_Precompute
 
class EC_Point_Multi_Point_Precompute
 
class EC_Point_Var_Point_Precompute
 
void swap (EC_Point &x, EC_Point &y)
 

Detailed Description

This class represents one point on a curve of GF(p)

Definition at line 33 of file ec_point.h.

Member Typedef Documentation

◆ Compression_Type

Definition at line 39 of file ec_point.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
WORKSPACE_SIZE 

Definition at line 42 of file ec_point.h.

42{ WORKSPACE_SIZE = 8 };

Constructor & Destructor Documentation

◆ EC_Point() [1/5]

Botan::EC_Point::EC_Point ( )
default

Construct an uninitialized EC_Point

Referenced by mult2(), mult2i(), and operator-=().

◆ EC_Point() [2/5]

Botan::EC_Point::EC_Point ( const CurveGFp & curve)
explicit

Construct the zero point

Parameters
curveThe base curve

Definition at line 19 of file ec_point.cpp.

19 : m_curve(curve), m_coord_x(0), m_coord_y(curve.get_1_rep()), m_coord_z(0) {
20 // Assumes Montgomery rep of zero is zero
21}

◆ EC_Point() [3/5]

Botan::EC_Point::EC_Point ( const EC_Point & )
default

Copy constructor

◆ EC_Point() [4/5]

Botan::EC_Point::EC_Point ( EC_Point && other)
inline

Move Constructor

Definition at line 63 of file ec_point.h.

63{ this->swap(other); }
friend void swap(EC_Point &x, EC_Point &y)
Definition ec_point.h:250

◆ EC_Point() [5/5]

Botan::EC_Point::EC_Point ( const CurveGFp & curve,
const BigInt & x,
const BigInt & y )

Construct a point from its affine coordinates Prefer EC_Group::point(x,y) for this operation.

Parameters
curvethe base curve
xaffine x coordinate
yaffine y coordinate

Definition at line 23 of file ec_point.cpp.

23 :
24 m_curve(curve), m_coord_x(x), m_coord_y(y), m_coord_z(m_curve.get_1_rep()) {
25 if(x < 0 || x >= curve.get_p()) {
26 throw Invalid_Argument("Invalid EC_Point affine x");
27 }
28 if(y < 0 || y >= curve.get_p()) {
29 throw Invalid_Argument("Invalid EC_Point affine y");
30 }
31
32 secure_vector<word> monty_ws(m_curve.get_ws_size());
33 m_curve.to_rep(m_coord_x, monty_ws);
34 m_curve.to_rep(m_coord_y, monty_ws);
35}
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61

References Botan::CurveGFp::get_p().

Member Function Documentation

◆ add() [1/2]

void Botan::EC_Point::add ( const EC_Point & other,
std::vector< BigInt > & workspace )
inline

Point addition

Parameters
otherthe point to add to *this
workspacetemp space, at least WORKSPACE_SIZE elements

Definition at line 263 of file ec_point.h.

263 {
264 BOTAN_ARG_CHECK(m_curve == other.m_curve, "cannot add points on different curves");
265
266 const size_t p_words = m_curve.get_p_words();
267
268 add(other.m_coord_x._data(),
269 std::min(p_words, other.m_coord_x.size()),
270 other.m_coord_y._data(),
271 std::min(p_words, other.m_coord_y.size()),
272 other.m_coord_z._data(),
273 std::min(p_words, other.m_coord_z.size()),
274 workspace);
275 }
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29
void add(const EC_Point &other, std::vector< BigInt > &workspace)
Definition ec_point.h:263

References Botan::BigInt::_data(), BOTAN_ARG_CHECK, and Botan::BigInt::size().

Referenced by mul(), Botan::EC_Point_Var_Point_Precompute::mul(), Botan::EC_Point_Multi_Point_Precompute::multi_exp(), operator+=(), and plus().

◆ add() [2/2]

void Botan::EC_Point::add ( const word x_words[],
size_t x_size,
const word y_words[],
size_t y_size,
const word z_words[],
size_t z_size,
std::vector< BigInt > & workspace )

Point addition. Array version.

Parameters
x_wordsthe words of the x coordinate of the other point
x_sizesize of x_words
y_wordsthe words of the y coordinate of the other point
y_sizesize of y_words
z_wordsthe words of the z coordinate of the other point
z_sizesize of z_words
workspacetemp space, at least WORKSPACE_SIZE elements

Definition at line 151 of file ec_point.cpp.

157 {
158 if((CT::all_zeros(x_words, x_size) & CT::all_zeros(z_words, z_size)).as_bool()) {
159 return;
160 }
161
162 if(is_zero()) {
163 m_coord_x.set_words(x_words, x_size);
164 m_coord_y.set_words(y_words, y_size);
165 m_coord_z.set_words(z_words, z_size);
166 return;
167 }
168
169 resize_ws(ws_bn, m_curve.get_ws_size());
170
171 secure_vector<word>& ws = ws_bn[0].get_word_vector();
172 secure_vector<word>& sub_ws = ws_bn[1].get_word_vector();
173
174 BigInt& T0 = ws_bn[2];
175 BigInt& T1 = ws_bn[3];
176 BigInt& T2 = ws_bn[4];
177 BigInt& T3 = ws_bn[5];
178 BigInt& T4 = ws_bn[6];
179 BigInt& T5 = ws_bn[7];
180
181 /*
182 https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-1998-cmo-2
183 */
184
185 const BigInt& p = m_curve.get_p();
186
187 m_curve.sqr(T0, z_words, z_size, ws); // z2^2
188 m_curve.mul(T1, m_coord_x, T0, ws); // x1*z2^2
189 m_curve.mul(T3, z_words, z_size, T0, ws); // z2^3
190 m_curve.mul(T2, m_coord_y, T3, ws); // y1*z2^3
191
192 m_curve.sqr(T3, m_coord_z, ws); // z1^2
193 m_curve.mul(T4, x_words, x_size, T3, ws); // x2*z1^2
194
195 m_curve.mul(T5, m_coord_z, T3, ws); // z1^3
196 m_curve.mul(T0, y_words, y_size, T5, ws); // y2*z1^3
197
198 T4.mod_sub(T1, p, sub_ws); // x2*z1^2 - x1*z2^2
199
200 T0.mod_sub(T2, p, sub_ws);
201
202 if(T4.is_zero()) {
203 if(T0.is_zero()) {
204 mult2(ws_bn);
205 return;
206 }
207
208 // setting to zero:
209 m_coord_x.clear();
210 m_coord_y = m_curve.get_1_rep();
211 m_coord_z.clear();
212 return;
213 }
214
215 m_curve.sqr(T5, T4, ws);
216
217 m_curve.mul(T3, T1, T5, ws);
218
219 m_curve.mul(T1, T5, T4, ws);
220
221 m_curve.sqr(m_coord_x, T0, ws);
222 m_coord_x.mod_sub(T1, p, sub_ws);
223 m_coord_x.mod_sub(T3, p, sub_ws);
224 m_coord_x.mod_sub(T3, p, sub_ws);
225
226 T3.mod_sub(m_coord_x, p, sub_ws);
227
228 m_curve.mul(m_coord_y, T0, T3, ws);
229 m_curve.mul(T3, T2, T1, ws);
230
231 m_coord_y.mod_sub(T3, p, sub_ws);
232
233 m_curve.mul(T3, z_words, z_size, m_coord_z, ws);
234 m_curve.mul(m_coord_z, T3, T4, ws);
235}
void set_words(const word w[], size_t len)
Definition bigint.h:551
BigInt & mod_sub(const BigInt &y, const BigInt &mod, secure_vector< word > &ws)
Definition big_ops2.cpp:90
void clear()
Definition bigint.h:399
const BigInt & get_p() const
Definition curve_gfp.h:109
void mult2(std::vector< BigInt > &workspace)
Definition ec_point.cpp:257
bool is_zero() const
Definition ec_point.h:156
constexpr CT::Mask< T > all_zeros(const T elem[], size_t len)
Definition ct_utils.h:473

References Botan::CT::all_zeros(), Botan::BigInt::clear(), Botan::CurveGFp::get_p(), Botan::BigInt::is_zero(), is_zero(), Botan::BigInt::mod_sub(), mult2(), and Botan::BigInt::set_words().

◆ add_affine() [1/2]

void Botan::EC_Point::add_affine ( const EC_Point & other,
std::vector< BigInt > & workspace )
inline

Point addition - mixed J+A

Parameters
otheraffine point to add - assumed to be affine!
workspacetemp space, at least WORKSPACE_SIZE elements

Definition at line 301 of file ec_point.h.

301 {
302 BOTAN_ASSERT_NOMSG(m_curve == other.m_curve);
303 BOTAN_DEBUG_ASSERT(other.is_affine());
304
305 const size_t p_words = m_curve.get_p_words();
306 add_affine(other.m_coord_x._data(),
307 std::min(p_words, other.m_coord_x.size()),
308 other.m_coord_y._data(),
309 std::min(p_words, other.m_coord_y.size()),
310 workspace);
311 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
#define BOTAN_DEBUG_ASSERT(expr)
Definition assert.h:98
void add_affine(const EC_Point &other, std::vector< BigInt > &workspace)
Definition ec_point.h:301

References Botan::BigInt::_data(), BOTAN_ASSERT_NOMSG, BOTAN_DEBUG_ASSERT, is_affine(), and Botan::BigInt::size().

Referenced by Botan::EC_Point_Base_Point_Precompute::mul(), and Botan::EC_Point_Multi_Point_Precompute::multi_exp().

◆ add_affine() [2/2]

void Botan::EC_Point::add_affine ( const word x_words[],
size_t x_size,
const word y_words[],
size_t y_size,
std::vector< BigInt > & workspace )

Point addition - mixed J+A. Array version.

Parameters
x_wordsthe words of the x coordinate of the other point
x_sizesize of x_words
y_wordsthe words of the y coordinate of the other point
y_sizesize of y_words
workspacetemp space, at least WORKSPACE_SIZE elements

Definition at line 74 of file ec_point.cpp.

75 {
76 if((CT::all_zeros(x_words, x_size) & CT::all_zeros(y_words, y_size)).as_bool()) {
77 return;
78 }
79
80 if(is_zero()) {
81 m_coord_x.set_words(x_words, x_size);
82 m_coord_y.set_words(y_words, y_size);
83 m_coord_z = m_curve.get_1_rep();
84 return;
85 }
86
87 resize_ws(ws_bn, m_curve.get_ws_size());
88
89 secure_vector<word>& ws = ws_bn[0].get_word_vector();
90 secure_vector<word>& sub_ws = ws_bn[1].get_word_vector();
91
92 BigInt& T0 = ws_bn[2];
93 BigInt& T1 = ws_bn[3];
94 BigInt& T2 = ws_bn[4];
95 BigInt& T3 = ws_bn[5];
96 BigInt& T4 = ws_bn[6];
97
98 /*
99 https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-1998-cmo-2
100 simplified with Z2 = 1
101 */
102
103 const BigInt& p = m_curve.get_p();
104
105 m_curve.sqr(T3, m_coord_z, ws); // z1^2
106 m_curve.mul(T4, x_words, x_size, T3, ws); // x2*z1^2
107
108 m_curve.mul(T2, m_coord_z, T3, ws); // z1^3
109 m_curve.mul(T0, y_words, y_size, T2, ws); // y2*z1^3
110
111 T4.mod_sub(m_coord_x, p, sub_ws); // x2*z1^2 - x1*z2^2
112
113 T0.mod_sub(m_coord_y, p, sub_ws);
114
115 if(T4.is_zero()) {
116 if(T0.is_zero()) {
117 mult2(ws_bn);
118 return;
119 }
120
121 // setting to zero:
122 m_coord_x.clear();
123 m_coord_y = m_curve.get_1_rep();
124 m_coord_z.clear();
125 return;
126 }
127
128 m_curve.sqr(T2, T4, ws);
129
130 m_curve.mul(T3, m_coord_x, T2, ws);
131
132 m_curve.mul(T1, T2, T4, ws);
133
134 m_curve.sqr(m_coord_x, T0, ws);
135 m_coord_x.mod_sub(T1, p, sub_ws);
136
137 m_coord_x.mod_sub(T3, p, sub_ws);
138 m_coord_x.mod_sub(T3, p, sub_ws);
139
140 T3.mod_sub(m_coord_x, p, sub_ws);
141
142 m_curve.mul(T2, T0, T3, ws);
143 m_curve.mul(T0, m_coord_y, T1, ws);
144 T2.mod_sub(T0, p, sub_ws);
145 m_coord_y.swap(T2);
146
147 m_curve.mul(T0, m_coord_z, T4, ws);
148 m_coord_z.swap(T0);
149}
void swap(BigInt &other)
Definition bigint.h:191

References Botan::CT::all_zeros(), Botan::BigInt::clear(), Botan::CurveGFp::get_p(), Botan::BigInt::is_zero(), is_zero(), Botan::BigInt::mod_sub(), mult2(), Botan::BigInt::set_words(), and Botan::BigInt::swap().

◆ double_of()

EC_Point Botan::EC_Point::double_of ( std::vector< BigInt > & workspace) const
inline

Point doubling

Parameters
workspacetemp space, at least WORKSPACE_SIZE elements
Returns
*this doubled

Definition at line 355 of file ec_point.h.

355 {
356 EC_Point x = (*this);
357 x.mult2(workspace);
358 return x;
359 }
EC_Point()=default

References mult2().

Referenced by Botan::EC_Point_Var_Point_Precompute::EC_Point_Var_Point_Precompute().

◆ encode()

std::vector< uint8_t > Botan::EC_Point::encode ( EC_Point_Format format) const

EC2OSP - elliptic curve to octet string primitive

Parameters
formatwhich format to encode using

Definition at line 589 of file ec_point.cpp.

589 {
590 if(is_zero()) {
591 return std::vector<uint8_t>(1); // single 0 byte
592 }
593
594 const size_t p_bytes = m_curve.get_p().bytes();
595
596 const BigInt x = get_affine_x();
597 const BigInt y = get_affine_y();
598
599 const size_t parts = (format == EC_Point_Format::Compressed) ? 1 : 2;
600
601 std::vector<uint8_t> result(1 + parts * p_bytes);
602 BufferStuffer stuffer(result);
603
604 if(format == EC_Point_Format::Uncompressed) {
605 stuffer.append(0x04);
606 x.serialize_to(stuffer.next(p_bytes));
607 y.serialize_to(stuffer.next(p_bytes));
608 } else if(format == EC_Point_Format::Compressed) {
609 stuffer.append(0x02 | static_cast<uint8_t>(y.get_bit(0)));
610 x.serialize_to(stuffer.next(p_bytes));
611 } else if(format == EC_Point_Format::Hybrid) {
612 stuffer.append(0x06 | static_cast<uint8_t>(y.get_bit(0)));
613 x.serialize_to(stuffer.next(p_bytes));
614 y.serialize_to(stuffer.next(p_bytes));
615 } else {
616 throw Invalid_Argument("EC2OSP illegal point encoding");
617 }
618
619 return result;
620}
size_t bytes() const
Definition bigint.cpp:282
BigInt get_affine_x() const
Definition ec_point.cpp:490
BigInt get_affine_y() const
Definition ec_point.cpp:510

References Botan::BufferStuffer::append(), Botan::BigInt::bytes(), Botan::Compressed, get_affine_x(), get_affine_y(), Botan::BigInt::get_bit(), Botan::CurveGFp::get_p(), Botan::Hybrid, is_zero(), Botan::BufferStuffer::next(), Botan::BigInt::serialize_to(), and Botan::Uncompressed.

Referenced by Botan::ECIES_KA_Operation::derive_secret(), Botan::ECIES_Encryptor::ECIES_Encryptor(), Botan::EC_PrivateKey::private_key_bits(), and Botan::EC_PublicKey::raw_public_key_bits().

◆ force_affine()

void Botan::EC_Point::force_affine ( )

Force this point to affine coordinates

Definition at line 449 of file ec_point.cpp.

449 {
450 if(is_zero()) {
451 throw Invalid_State("Cannot convert zero ECC point to affine");
452 }
453
455
456 const BigInt z_inv = m_curve.invert_element(m_coord_z, ws);
457 const BigInt z2_inv = m_curve.sqr_to_tmp(z_inv, ws);
458 const BigInt z3_inv = m_curve.mul_to_tmp(z_inv, z2_inv, ws);
459 m_coord_x = m_curve.mul_to_tmp(m_coord_x, z2_inv, ws);
460 m_coord_y = m_curve.mul_to_tmp(m_coord_y, z3_inv, ws);
461 m_coord_z = m_curve.get_1_rep();
462}

References is_zero().

Referenced by force_all_affine().

◆ force_all_affine()

void Botan::EC_Point::force_all_affine ( std::span< EC_Point > points,
secure_vector< word > & ws )
static

Force all points on the list to affine coordinates

Definition at line 387 of file ec_point.cpp.

387 {
388 if(points.size() <= 1) {
389 for(auto& point : points) {
390 point.force_affine();
391 }
392 return;
393 }
394
395 for(auto& point : points) {
396 if(point.is_zero()) {
397 throw Invalid_State("Cannot convert zero ECC point to affine");
398 }
399 }
400
401 /*
402 For >= 2 points use Montgomery's trick
403
404 See Algorithm 2.26 in "Guide to Elliptic Curve Cryptography"
405 (Hankerson, Menezes, Vanstone)
406
407 TODO is it really necessary to save all k points in c?
408 */
409
410 const CurveGFp& curve = points[0].m_curve;
411 const BigInt& rep_1 = curve.get_1_rep();
412
413 if(ws.size() < curve.get_ws_size()) {
414 ws.resize(curve.get_ws_size());
415 }
416
417 std::vector<BigInt> c(points.size());
418 c[0] = points[0].m_coord_z;
419
420 for(size_t i = 1; i != points.size(); ++i) {
421 curve.mul(c[i], c[i - 1], points[i].m_coord_z, ws);
422 }
423
424 BigInt s_inv = curve.invert_element(c[c.size() - 1], ws);
425
426 BigInt z_inv, z2_inv, z3_inv;
427
428 for(size_t i = points.size() - 1; i != 0; i--) {
429 EC_Point& point = points[i];
430
431 curve.mul(z_inv, s_inv, c[i - 1], ws);
432
433 s_inv = curve.mul_to_tmp(s_inv, point.m_coord_z, ws);
434
435 curve.sqr(z2_inv, z_inv, ws);
436 curve.mul(z3_inv, z2_inv, z_inv, ws);
437 point.m_coord_x = curve.mul_to_tmp(point.m_coord_x, z2_inv, ws);
438 point.m_coord_y = curve.mul_to_tmp(point.m_coord_y, z3_inv, ws);
439 point.m_coord_z = rep_1;
440 }
441
442 curve.sqr(z2_inv, s_inv, ws);
443 curve.mul(z3_inv, z2_inv, s_inv, ws);
444 points[0].m_coord_x = curve.mul_to_tmp(points[0].m_coord_x, z2_inv, ws);
445 points[0].m_coord_y = curve.mul_to_tmp(points[0].m_coord_y, z3_inv, ws);
446 points[0].m_coord_z = rep_1;
447}

References force_affine(), and Botan::BigInt::resize().

Referenced by Botan::EC_Point_Base_Point_Precompute::EC_Point_Base_Point_Precompute(), and Botan::EC_Point_Multi_Point_Precompute::EC_Point_Multi_Point_Precompute().

◆ get_affine_x()

BigInt Botan::EC_Point::get_affine_x ( ) const

get affine x coordinate

Returns
affine x coordinate

Definition at line 490 of file ec_point.cpp.

490 {
491 if(is_zero()) {
492 throw Invalid_State("Cannot convert zero point to affine");
493 }
494
495 secure_vector<word> monty_ws;
496
497 if(is_affine()) {
498 return m_curve.from_rep_to_tmp(m_coord_x, monty_ws);
499 }
500
501 BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws);
502 z2 = m_curve.invert_element(z2, monty_ws);
503
504 BigInt r;
505 m_curve.mul(r, m_coord_x, z2, monty_ws);
506 m_curve.from_rep(r, monty_ws);
507 return r;
508}
bool is_affine() const
Definition ec_point.cpp:464

References is_affine(), and is_zero().

Referenced by Botan::EC_Group::blinded_base_point_multiply_x(), encode(), operator==(), and xy_bytes().

◆ get_affine_y()

BigInt Botan::EC_Point::get_affine_y ( ) const

get affine y coordinate

Returns
affine y coordinate

Definition at line 510 of file ec_point.cpp.

510 {
511 if(is_zero()) {
512 throw Invalid_State("Cannot convert zero point to affine");
513 }
514
515 secure_vector<word> monty_ws;
516
517 if(is_affine()) {
518 return m_curve.from_rep_to_tmp(m_coord_y, monty_ws);
519 }
520
521 const BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws);
522 const BigInt z3 = m_curve.mul_to_tmp(m_coord_z, z2, monty_ws);
523 const BigInt z3_inv = m_curve.invert_element(z3, monty_ws);
524
525 BigInt r;
526 m_curve.mul(r, m_coord_y, z3_inv, monty_ws);
527 m_curve.from_rep(r, monty_ws);
528 return r;
529}

References is_affine(), and is_zero().

Referenced by encode(), operator==(), and xy_bytes().

◆ get_curve()

const CurveGFp & Botan::EC_Point::get_curve ( ) const
inline

Return base curve of this point

Returns
the curve over GF(p) of this point

You should not need to use this

Definition at line 367 of file ec_point.h.

367{ return m_curve; }

◆ get_x()

const BigInt & Botan::EC_Point::get_x ( ) const
inline

Return the internal x coordinate

Note this may be in Montgomery form

Definition at line 226 of file ec_point.h.

226{ return m_coord_x; }

◆ get_y()

const BigInt & Botan::EC_Point::get_y ( ) const
inline

Return the internal y coordinate

Note this may be in Montgomery form

Definition at line 233 of file ec_point.h.

233{ return m_coord_y; }

◆ get_z()

const BigInt & Botan::EC_Point::get_z ( ) const
inline

Return the internal z coordinate

Note this may be in Montgomery form

Definition at line 240 of file ec_point.h.

240{ return m_coord_z; }

◆ is_affine()

bool Botan::EC_Point::is_affine ( ) const

Definition at line 464 of file ec_point.cpp.

464 {
465 return m_curve.is_one(m_coord_z);
466}

Referenced by add_affine(), get_affine_x(), and get_affine_y().

◆ is_zero()

bool Botan::EC_Point::is_zero ( ) const
inline

Is this the point at infinity?

Returns
true, if this point is at infinity, false otherwise.

Definition at line 156 of file ec_point.h.

156{ return m_coord_z.is_zero(); }
bool is_zero() const
Definition bigint.h:457

Referenced by add(), add_affine(), Botan::EC_Group::blinded_base_point_multiply_x(), Botan::ECIES_KA_Operation::derive_secret(), encode(), force_affine(), get_affine_x(), get_affine_y(), mult2(), on_the_curve(), operator-=(), operator==(), and Botan::EC_Group::verify_public_element().

◆ mul()

EC_Point Botan::EC_Point::mul ( const BigInt & scalar) const

Point multiplication operator

Simple unblinded Montgomery ladder

Warning: prefer the functions on EC_Group such as blinded_var_point_multiply

Parameters
scalarthe scalar value
Returns
*this multiplied by the scalar value

Definition at line 364 of file ec_point.cpp.

364 {
365 const size_t scalar_bits = scalar.bits();
366
367 std::vector<BigInt> ws(EC_Point::WORKSPACE_SIZE);
368
369 EC_Point R[2] = {this->zero(), *this};
370
371 for(size_t i = scalar_bits; i > 0; i--) {
372 const size_t b = scalar.get_bit(i - 1);
373 R[b ^ 1].add(R[b], ws);
374 R[b].mult2(ws);
375 }
376
377 if(scalar.is_negative()) {
378 R[0].negate();
379 }
380
382
383 return R[0];
384}
bool on_the_curve() const
Definition ec_point.cpp:531
EC_Point zero() const
Definition ec_point.h:195

References add(), Botan::BigInt::bits(), BOTAN_DEBUG_ASSERT, Botan::BigInt::get_bit(), Botan::BigInt::is_negative(), mult2(), negate(), on_the_curve(), WORKSPACE_SIZE, and zero().

Referenced by Botan::operator*(), and Botan::operator*().

◆ mult2()

void Botan::EC_Point::mult2 ( std::vector< BigInt > & workspace)

Point doubling

Parameters
workspacetemp space, at least WORKSPACE_SIZE elements

Definition at line 257 of file ec_point.cpp.

257 {
258 if(is_zero()) {
259 return;
260 }
261
262 if(m_coord_y.is_zero()) {
263 *this = EC_Point(m_curve); // setting myself to zero
264 return;
265 }
266
267 resize_ws(ws_bn, m_curve.get_ws_size());
268
269 secure_vector<word>& ws = ws_bn[0].get_word_vector();
270 secure_vector<word>& sub_ws = ws_bn[1].get_word_vector();
271
272 BigInt& T0 = ws_bn[2];
273 BigInt& T1 = ws_bn[3];
274 BigInt& T2 = ws_bn[4];
275 BigInt& T3 = ws_bn[5];
276 BigInt& T4 = ws_bn[6];
277
278 /*
279 https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-1986-cc
280 */
281 const BigInt& p = m_curve.get_p();
282
283 m_curve.sqr(T0, m_coord_y, ws);
284
285 m_curve.mul(T1, m_coord_x, T0, ws);
286 T1.mod_mul(4, p, sub_ws);
287
288 if(m_curve.a_is_zero()) {
289 // if a == 0 then 3*x^2 + a*z^4 is just 3*x^2
290 m_curve.sqr(T4, m_coord_x, ws); // x^2
291 T4.mod_mul(3, p, sub_ws); // 3*x^2
292 } else if(m_curve.a_is_minus_3()) {
293 /*
294 if a == -3 then
295 3*x^2 + a*z^4 == 3*x^2 - 3*z^4 == 3*(x^2-z^4) == 3*(x-z^2)*(x+z^2)
296 */
297 m_curve.sqr(T3, m_coord_z, ws); // z^2
298
299 // (x-z^2)
300 T2 = m_coord_x;
301 T2.mod_sub(T3, p, sub_ws);
302
303 // (x+z^2)
304 T3.mod_add(m_coord_x, p, sub_ws);
305
306 m_curve.mul(T4, T2, T3, ws); // (x-z^2)*(x+z^2)
307
308 T4.mod_mul(3, p, sub_ws); // 3*(x-z^2)*(x+z^2)
309 } else {
310 m_curve.sqr(T3, m_coord_z, ws); // z^2
311 m_curve.sqr(T4, T3, ws); // z^4
312 m_curve.mul(T3, m_curve.get_a_rep(), T4, ws); // a*z^4
313
314 m_curve.sqr(T4, m_coord_x, ws); // x^2
315 T4.mod_mul(3, p, sub_ws);
316 T4.mod_add(T3, p, sub_ws); // 3*x^2 + a*z^4
317 }
318
319 m_curve.sqr(T2, T4, ws);
320 T2.mod_sub(T1, p, sub_ws);
321 T2.mod_sub(T1, p, sub_ws);
322
323 m_curve.sqr(T3, T0, ws);
324 T3.mod_mul(8, p, sub_ws);
325
326 T1.mod_sub(T2, p, sub_ws);
327
328 m_curve.mul(T0, T4, T1, ws);
329 T0.mod_sub(T3, p, sub_ws);
330
331 m_coord_x.swap(T2);
332
333 m_curve.mul(T2, m_coord_y, m_coord_z, ws);
334 T2.mod_mul(2, p, sub_ws);
335
336 m_coord_y.swap(T0);
337 m_coord_z.swap(T2);
338}
BigInt & mod_add(const BigInt &y, const BigInt &mod, secure_vector< word > &ws)
Definition big_ops2.cpp:45

References EC_Point(), Botan::CurveGFp::get_p(), Botan::BigInt::is_zero(), is_zero(), Botan::BigInt::mod_add(), Botan::BigInt::mod_mul(), Botan::BigInt::mod_sub(), and Botan::BigInt::swap().

Referenced by add(), add_affine(), double_of(), Botan::EC_Point_Base_Point_Precompute::EC_Point_Base_Point_Precompute(), Botan::EC_Point_Multi_Point_Precompute::EC_Point_Multi_Point_Precompute(), mul(), and mult2i().

◆ mult2i()

void Botan::EC_Point::mult2i ( size_t i,
std::vector< BigInt > & workspace )

Repeated point doubling

Parameters
inumber of doublings to perform
workspacetemp space, at least WORKSPACE_SIZE elements

Definition at line 237 of file ec_point.cpp.

237 {
238 if(iterations == 0) {
239 return;
240 }
241
242 if(m_coord_y.is_zero()) {
243 *this = EC_Point(m_curve); // setting myself to zero
244 return;
245 }
246
247 /*
248 TODO we can save 2 squarings per iteration by computing
249 a*Z^4 using values cached from previous iteration
250 */
251 for(size_t i = 0; i != iterations; ++i) {
252 mult2(ws_bn);
253 }
254}

References EC_Point(), Botan::BigInt::is_zero(), and mult2().

Referenced by Botan::EC_Point_Var_Point_Precompute::mul(), and Botan::EC_Point_Multi_Point_Precompute::multi_exp().

◆ negate()

EC_Point & Botan::EC_Point::negate ( )
inline

Negate this point

Returns
*this

Definition at line 133 of file ec_point.h.

133 {
134 if(!is_zero()) {
135 m_coord_y = m_curve.get_p() - m_coord_y;
136 }
137 return *this;
138 }

Referenced by mul(), Botan::EC_Point_Multi_Point_Precompute::multi_exp(), Botan::operator-(), and operator-=().

◆ on_the_curve()

bool Botan::EC_Point::on_the_curve ( ) const

Checks whether the point is to be found on the underlying curve; used to prevent fault attacks.

Returns
if the point is on the curve

Definition at line 531 of file ec_point.cpp.

531 {
532 /*
533 Is the point still on the curve?? (If everything is correct, the
534 point is always on its curve; then the function will return true.
535 If somehow the state is corrupted, which suggests a fault attack
536 (or internal computational error), then return false.
537 */
538 if(is_zero()) {
539 return true;
540 }
541
542 secure_vector<word> monty_ws;
543
544 const BigInt y2 = m_curve.from_rep_to_tmp(m_curve.sqr_to_tmp(m_coord_y, monty_ws), monty_ws);
545 const BigInt x3 = m_curve.mul_to_tmp(m_coord_x, m_curve.sqr_to_tmp(m_coord_x, monty_ws), monty_ws);
546 const BigInt ax = m_curve.mul_to_tmp(m_coord_x, m_curve.get_a_rep(), monty_ws);
547 const BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws);
548
549 if(m_coord_z == z2) // Is z equal to 1 (in Montgomery form)?
550 {
551 if(y2 != m_curve.from_rep_to_tmp(x3 + ax + m_curve.get_b_rep(), monty_ws)) {
552 return false;
553 }
554 }
555
556 const BigInt z3 = m_curve.mul_to_tmp(m_coord_z, z2, monty_ws);
557 const BigInt ax_z4 = m_curve.mul_to_tmp(ax, m_curve.sqr_to_tmp(z2, monty_ws), monty_ws);
558 const BigInt b_z6 = m_curve.mul_to_tmp(m_curve.get_b_rep(), m_curve.sqr_to_tmp(z3, monty_ws), monty_ws);
559
560 if(y2 != m_curve.from_rep_to_tmp(x3 + ax_z4 + b_z6, monty_ws)) {
561 return false;
562 }
563
564 return true;
565}

References is_zero().

Referenced by Botan::EC_Point_Multi_Point_Precompute::EC_Point_Multi_Point_Precompute(), Botan::EC_PrivateKey::EC_PrivateKey(), Botan::EC_PrivateKey::EC_PrivateKey(), Botan::GOST_3410_PublicKey::GOST_3410_PublicKey(), mul(), Botan::EC_Point_Base_Point_Precompute::mul(), Botan::EC_Point_Var_Point_Precompute::mul(), Botan::OS2ECP(), Botan::EC_Group::verify_group(), and Botan::EC_Group::verify_public_element().

◆ operator!=()

bool Botan::EC_Point::operator!= ( const EC_Point & other) const
default

◆ operator*=()

EC_Point & Botan::EC_Point::operator*= ( const BigInt & scalar)

*= Operator

Parameters
scalarthe EC_Point to multiply with *this
Returns
resulting EC_Point

Definition at line 359 of file ec_point.cpp.

359 {
360 *this = scalar * *this;
361 return *this;
362}

◆ operator+=()

EC_Point & Botan::EC_Point::operator+= ( const EC_Point & rhs)

+= Operator

Parameters
rhsthe EC_Point to add to the local value
Returns
resulting EC_Point

Definition at line 341 of file ec_point.cpp.

341 {
342 std::vector<BigInt> ws(EC_Point::WORKSPACE_SIZE);
343 add(rhs, ws);
344 return *this;
345}

References add(), and WORKSPACE_SIZE.

◆ operator-=()

EC_Point & Botan::EC_Point::operator-= ( const EC_Point & rhs)

-= Operator

Parameters
rhsthe EC_Point to subtract from the local value
Returns
resulting EC_Point

Definition at line 347 of file ec_point.cpp.

347 {
348 EC_Point minus_rhs = EC_Point(rhs).negate();
349
350 if(is_zero()) {
351 *this = minus_rhs;
352 } else {
353 *this += minus_rhs;
354 }
355
356 return *this;
357}

References EC_Point(), is_zero(), and negate().

◆ operator=() [1/2]

EC_Point & Botan::EC_Point::operator= ( const EC_Point & )
default

Standard Assignment

◆ operator=() [2/2]

EC_Point & Botan::EC_Point::operator= ( EC_Point && other)
inline

Move Assignment

Definition at line 73 of file ec_point.h.

73 {
74 if(this != &other) {
75 this->swap(other);
76 }
77 return (*this);
78 }

◆ operator==()

bool Botan::EC_Point::operator== ( const EC_Point & other) const

Equality operator

Definition at line 575 of file ec_point.cpp.

575 {
576 if(m_curve != other.m_curve) {
577 return false;
578 }
579
580 // If this is zero, only equal if other is also zero
581 if(is_zero()) {
582 return other.is_zero();
583 }
584
585 return (get_affine_x() == other.get_affine_x() && get_affine_y() == other.get_affine_y());
586}

References get_affine_x(), get_affine_y(), and is_zero().

◆ plus()

EC_Point Botan::EC_Point::plus ( const EC_Point & other,
std::vector< BigInt > & workspace ) const
inline

Point addition

Parameters
otherthe point to add to *this
workspacetemp space, at least WORKSPACE_SIZE elements
Returns
other plus *this

Definition at line 344 of file ec_point.h.

344 {
345 EC_Point x = (*this);
346 x.add(other, workspace);
347 return x;
348 }

References add().

Referenced by Botan::EC_Point_Base_Point_Precompute::EC_Point_Base_Point_Precompute(), Botan::EC_Point_Multi_Point_Precompute::EC_Point_Multi_Point_Precompute(), and Botan::EC_Point_Var_Point_Precompute::EC_Point_Var_Point_Precompute().

◆ randomize_repr() [1/2]

void Botan::EC_Point::randomize_repr ( RandomNumberGenerator & rng)

Randomize the point representation The actual value (get_affine_x, get_affine_y) does not change

Definition at line 37 of file ec_point.cpp.

37 {
38 secure_vector<word> ws(m_curve.get_ws_size());
39 randomize_repr(rng, ws);
40}
void randomize_repr(RandomNumberGenerator &rng)
Definition ec_point.cpp:37

References randomize_repr().

Referenced by Botan::EC_Point_Var_Point_Precompute::EC_Point_Var_Point_Precompute(), Botan::EC_Point_Base_Point_Precompute::mul(), Botan::EC_Point_Var_Point_Precompute::mul(), and randomize_repr().

◆ randomize_repr() [2/2]

void Botan::EC_Point::randomize_repr ( RandomNumberGenerator & rng,
secure_vector< word > & ws )

Randomize the point representation The actual value (get_affine_x, get_affine_y) does not change

Definition at line 42 of file ec_point.cpp.

42 {
43 const BigInt mask = BigInt::random_integer(rng, 2, m_curve.get_p());
44
45 /*
46 * No reason to convert this to Montgomery representation first,
47 * just pretend the random mask was chosen as Redc(mask) and the
48 * random mask we generated above is in the Montgomery
49 * representation.
50 * //m_curve.to_rep(mask, ws);
51 */
52 const BigInt mask2 = m_curve.sqr_to_tmp(mask, ws);
53 const BigInt mask3 = m_curve.mul_to_tmp(mask2, mask, ws);
54
55 m_coord_x = m_curve.mul_to_tmp(m_coord_x, mask2, ws);
56 m_coord_y = m_curve.mul_to_tmp(m_coord_y, mask3, ws);
57 m_coord_z = m_curve.mul_to_tmp(m_coord_z, mask, ws);
58}
static BigInt random_integer(RandomNumberGenerator &rng, const BigInt &min, const BigInt &max)
Definition big_rand.cpp:43

References Botan::CurveGFp::get_p(), and Botan::BigInt::random_integer().

◆ swap()

void Botan::EC_Point::swap ( EC_Point & other)
noexcept

swaps the states of *this and other

Parameters
otherthe object to swap values with

Definition at line 568 of file ec_point.cpp.

568 {
569 m_curve.swap(other.m_curve);
570 m_coord_x.swap(other.m_coord_x);
571 m_coord_y.swap(other.m_coord_y);
572 m_coord_z.swap(other.m_coord_z);
573}

References Botan::BigInt::swap().

Referenced by Botan::EC_Point_Base_Point_Precompute::EC_Point_Base_Point_Precompute().

◆ swap_coords()

void Botan::EC_Point::swap_coords ( BigInt & new_x,
BigInt & new_y,
BigInt & new_z )
inline

Definition at line 244 of file ec_point.h.

244 {
245 m_coord_x.swap(new_x);
246 m_coord_y.swap(new_y);
247 m_coord_z.swap(new_z);
248 }

References Botan::BigInt::swap().

◆ x_bytes()

secure_vector< uint8_t > Botan::EC_Point::x_bytes ( ) const

Return the fixed length big endian encoding of x coordinate

Definition at line 468 of file ec_point.cpp.

468 {
469 const size_t p_bytes = m_curve.get_p_bytes();
470 secure_vector<uint8_t> b(p_bytes);
471 BigInt::encode_1363(b.data(), b.size(), this->get_affine_x());
472 return b;
473}
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition bigint.h:900

References Botan::BigInt::encode_1363().

◆ xy_bytes()

secure_vector< uint8_t > Botan::EC_Point::xy_bytes ( ) const

Return the fixed length concatenation of the x and y coordinates

Definition at line 482 of file ec_point.cpp.

482 {
483 const size_t p_bytes = m_curve.get_p_bytes();
484 secure_vector<uint8_t> b(2 * p_bytes);
485 BigInt::encode_1363(&b[0], p_bytes, this->get_affine_x());
486 BigInt::encode_1363(&b[p_bytes], p_bytes, this->get_affine_y());
487 return b;
488}

References Botan::BigInt::encode_1363(), get_affine_x(), and get_affine_y().

Referenced by Botan::GOST_3410_PublicKey::public_key_bits(), and Botan::sm2_compute_za().

◆ y_bytes()

secure_vector< uint8_t > Botan::EC_Point::y_bytes ( ) const

Return the fixed length big endian encoding of y coordinate

Definition at line 475 of file ec_point.cpp.

475 {
476 const size_t p_bytes = m_curve.get_p_bytes();
477 secure_vector<uint8_t> b(p_bytes);
478 BigInt::encode_1363(b.data(), b.size(), this->get_affine_y());
479 return b;
480}

References Botan::BigInt::encode_1363().

◆ zero()

EC_Point Botan::EC_Point::zero ( ) const
inline

Return the zero (aka infinite) point associated with this curve

Definition at line 195 of file ec_point.h.

195{ return EC_Point(m_curve); }

Referenced by Botan::EC_Point_Multi_Point_Precompute::EC_Point_Multi_Point_Precompute(), Botan::EC_Point_Var_Point_Precompute::EC_Point_Var_Point_Precompute(), mul(), and Botan::EC_Point_Base_Point_Precompute::mul().

Friends And Related Symbol Documentation

◆ EC_Point_Base_Point_Precompute

friend class EC_Point_Base_Point_Precompute
friend

Definition at line 37 of file ec_point.h.

◆ EC_Point_Multi_Point_Precompute

friend class EC_Point_Multi_Point_Precompute
friend

Definition at line 36 of file ec_point.h.

◆ EC_Point_Var_Point_Precompute

friend class EC_Point_Var_Point_Precompute
friend

Definition at line 35 of file ec_point.h.

◆ swap

void swap ( EC_Point & x,
EC_Point & y )
friend

Definition at line 250 of file ec_point.h.

250{ x.swap(y); }

The documentation for this class was generated from the following files: