Botan 3.6.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, BigInt x, 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

Deprecated elliptic curve type

Use EC_AffinePoint in new code

This type will be removed/hidden in Botan4

Definition at line 37 of file ec_point.h.

Member Typedef Documentation

◆ Compression_Type

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
WORKSPACE_SIZE 

Definition at line 46 of file ec_point.h.

46{ 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 67 of file ec_point.h.

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

◆ EC_Point() [5/5]

Botan::EC_Point::EC_Point ( const CurveGFp & curve,
BigInt x,
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(std::move(x)), m_coord_y(std::move(y)), m_coord_z(m_curve.get_1_rep()) {
25 if(m_coord_x < 0 || m_coord_x >= curve.get_p()) {
26 throw Invalid_Argument("Invalid EC_Point affine x");
27 }
28 if(m_coord_y < 0 || m_coord_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 275 of file ec_point.h.

275 {
276 BOTAN_ARG_CHECK(m_curve == other.m_curve, "cannot add points on different curves");
277
278 const size_t p_words = m_curve.get_p_words();
279
280 add(other.m_coord_x._data(),
281 std::min(p_words, other.m_coord_x.size()),
282 other.m_coord_y._data(),
283 std::min(p_words, other.m_coord_y.size()),
284 other.m_coord_z._data(),
285 std::min(p_words, other.m_coord_z.size()),
286 workspace);
287 }
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29
void add(const EC_Point &other, std::vector< BigInt > &workspace)
Definition ec_point.h:275

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:552
BigInt & mod_sub(const BigInt &y, const BigInt &mod, secure_vector< word > &ws)
Definition big_ops2.cpp:90
void clear()
Definition bigint.h:400
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:167
constexpr CT::Mask< T > all_zeros(const T elem[], size_t len)
Definition ct_utils.h:746

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

Warning
This function assumes that other is affine, if this is not correct the result will be invalid.
Parameters
otheraffine point to add - assumed to be affine!
workspacetemp space, at least WORKSPACE_SIZE elements

Definition at line 317 of file ec_point.h.

317 {
318 BOTAN_ASSERT_NOMSG(m_curve == other.m_curve);
319 BOTAN_DEBUG_ASSERT(other.is_affine());
320
321 const size_t p_words = m_curve.get_p_words();
322 add_affine(other.m_coord_x._data(),
323 std::min(p_words, other.m_coord_x.size()),
324 other.m_coord_y._data(),
325 std::min(p_words, other.m_coord_y.size()),
326 workspace);
327 }
#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:317

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:192

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 371 of file ec_point.h.

371 {
372 EC_Point x = (*this);
373 x.mult2(workspace);
374 return x;
375 }
EC_Point()=default

References mult2().

◆ 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(), and Botan::EC_PublicKey::raw_public_key_bits().

◆ force_affine()

void Botan::EC_Point::force_affine ( )

Force this point to affine coordinates

Convert the point to its equivalent affine coordinates. Throws if this is the point at infinity.

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().

◆ 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

Force several points to be affine at once. Uses Montgomery's trick to reduce number of inversions required, so this is much faster than calling force_affine on each point in sequence.

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}

Referenced by Botan::EC_Point_Base_Point_Precompute::EC_Point_Base_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 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 383 of file ec_point.h.

383{ 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 238 of file ec_point.h.

238{ 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 245 of file ec_point.h.

245{ 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 252 of file ec_point.h.

252{ 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

◆ 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:206
const SIMD_8x32 & b

References add(), Botan::b, 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 137 of file ec_point.h.

137 {
138 if(!is_zero()) {
139 m_coord_y = m_curve.get_p() - m_coord_y;
140 }
141 return *this;
142 }

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 // Is z equal to 1 (in Montgomery form)?
550 if(m_coord_z == z2) {
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(), 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 77 of file ec_point.h.

77 {
78 if(this != &other) {
79 this->swap(other);
80 }
81 return (*this);
82 }

◆ 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 360 of file ec_point.h.

360 {
361 EC_Point x = (*this);
362 x.add(other, workspace);
363 return x;
364 }

References add().

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().

◆ 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}

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 256 of file ec_point.h.

256 {
257 m_coord_x.swap(new_x);
258 m_coord_y.swap(new_y);
259 m_coord_z.swap(new_z);
260 }

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:905

References Botan::b, and 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::b, Botan::BigInt::encode_1363(), get_affine_x(), and get_affine_y().

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

◆ 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::b, and 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 206 of file ec_point.h.

206{ return EC_Point(m_curve); }

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

Friends And Related Symbol Documentation

◆ EC_Point_Base_Point_Precompute

friend class EC_Point_Base_Point_Precompute
friend

Definition at line 41 of file ec_point.h.

◆ EC_Point_Multi_Point_Precompute

friend class EC_Point_Multi_Point_Precompute
friend

Definition at line 40 of file ec_point.h.

◆ EC_Point_Var_Point_Precompute

friend class EC_Point_Var_Point_Precompute
friend

Definition at line 39 of file ec_point.h.

◆ swap

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

Definition at line 262 of file ec_point.h.

262{ x.swap(y); }

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