Botan 3.0.0
Crypto and TLS for C&
Public Types | Public Member Functions | Static Public Member Functions | List of all members
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
 
void mult2 (std::vector< BigInt > &workspace)
 
void mult2i (size_t i, std::vector< BigInt > &workspace)
 
EC_Pointnegate ()
 
bool on_the_curve () const
 
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)
 
void swap_coords (BigInt &new_x, BigInt &new_y, BigInt &new_z)
 
EC_Point zero () const
 

Static Public Member Functions

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

Detailed Description

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

Definition at line 32 of file ec_point.h.

Member Typedef Documentation

◆ Compression_Type

Definition at line 35 of file ec_point.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
WORKSPACE_SIZE 

Definition at line 38 of file ec_point.h.

38{ 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 17 of file ec_point.cpp.

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

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

60 {
61 this->swap(other);
62 }
void swap(EC_Point &other)
Definition: ec_point.cpp:578

◆ 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 26 of file ec_point.cpp.

26 :
27 m_curve(curve),
28 m_coord_x(x),
29 m_coord_y(y),
30 m_coord_z(m_curve.get_1_rep())
31 {
32 if(x < 0 || x >= curve.get_p())
33 throw Invalid_Argument("Invalid EC_Point affine x");
34 if(y < 0 || y >= curve.get_p())
35 throw Invalid_Argument("Invalid EC_Point affine y");
36
37 secure_vector<word> monty_ws(m_curve.get_ws_size());
38 m_curve.to_rep(m_coord_x, monty_ws);
39 m_curve.to_rep(m_coord_y, monty_ws);
40 }
static SIMD_4x64 y
size_t get_ws_size() const
Definition: curve_gfp.h:138
const BigInt & get_1_rep() const
Definition: curve_gfp.h:144
void to_rep(BigInt &x, secure_vector< word > &ws) const
Definition: curve_gfp.h:156

References Botan::CurveGFp::get_p(), Botan::CurveGFp::get_ws_size(), and Botan::CurveGFp::to_rep().

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

221 {
222 BOTAN_ARG_CHECK(m_curve == other.m_curve, "cannot add points on different curves");
223
224 const size_t p_words = m_curve.get_p_words();
225
226 add(other.m_coord_x.data(), std::min(p_words, other.m_coord_x.size()),
227 other.m_coord_y.data(), std::min(p_words, other.m_coord_y.size()),
228 other.m_coord_z.data(), std::min(p_words, other.m_coord_z.size()),
229 workspace);
230 }
#define BOTAN_ARG_CHECK(expr, msg)
Definition: assert.h:36
size_t get_p_words() const
Definition: curve_gfp.h:136
void add(const EC_Point &other, std::vector< BigInt > &workspace)
Definition: ec_point.h:220

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

Referenced by Botan::EC_Point_Var_Point_Precompute::mul(), Botan::EC_Point_Multi_Point_Precompute::multi_exp(), Botan::operator*(), 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 172 of file ec_point.cpp.

176 {
177 if(all_zeros(x_words, x_size) & all_zeros(z_words, z_size))
178 return;
179
180 if(is_zero())
181 {
182 m_coord_x.set_words(x_words, x_size);
183 m_coord_y.set_words(y_words, y_size);
184 m_coord_z.set_words(z_words, z_size);
185 return;
186 }
187
188 resize_ws(ws_bn, m_curve.get_ws_size());
189
190 secure_vector<word>& ws = ws_bn[0].get_word_vector();
191 secure_vector<word>& sub_ws = ws_bn[1].get_word_vector();
192
193 BigInt& T0 = ws_bn[2];
194 BigInt& T1 = ws_bn[3];
195 BigInt& T2 = ws_bn[4];
196 BigInt& T3 = ws_bn[5];
197 BigInt& T4 = ws_bn[6];
198 BigInt& T5 = ws_bn[7];
199
200 /*
201 https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-1998-cmo-2
202 */
203
204 const BigInt& p = m_curve.get_p();
205
206 m_curve.sqr(T0, z_words, z_size, ws); // z2^2
207 m_curve.mul(T1, m_coord_x, T0, ws); // x1*z2^2
208 m_curve.mul(T3, z_words, z_size, T0, ws); // z2^3
209 m_curve.mul(T2, m_coord_y, T3, ws); // y1*z2^3
210
211 m_curve.sqr(T3, m_coord_z, ws); // z1^2
212 m_curve.mul(T4, x_words, x_size, T3, ws); // x2*z1^2
213
214 m_curve.mul(T5, m_coord_z, T3, ws); // z1^3
215 m_curve.mul(T0, y_words, y_size, T5, ws); // y2*z1^3
216
217 T4.mod_sub(T1, p, sub_ws); // x2*z1^2 - x1*z2^2
218
219 T0.mod_sub(T2, p, sub_ws);
220
221 if(T4.is_zero())
222 {
223 if(T0.is_zero())
224 {
225 mult2(ws_bn);
226 return;
227 }
228
229 // setting to zero:
230 m_coord_x.clear();
231 m_coord_y = m_curve.get_1_rep();
232 m_coord_z.clear();
233 return;
234 }
235
236 m_curve.sqr(T5, T4, ws);
237
238 m_curve.mul(T3, T1, T5, ws);
239
240 m_curve.mul(T1, T5, T4, ws);
241
242 m_curve.sqr(m_coord_x, T0, ws);
243 m_coord_x.mod_sub(T1, p, sub_ws);
244 m_coord_x.mod_sub(T3, p, sub_ws);
245 m_coord_x.mod_sub(T3, p, sub_ws);
246
247 T3.mod_sub(m_coord_x, p, sub_ws);
248
249 m_curve.mul(m_coord_y, T0, T3, ws);
250 m_curve.mul(T3, T2, T1, ws);
251
252 m_coord_y.mod_sub(T3, p, sub_ws);
253
254 m_curve.mul(T3, z_words, z_size, m_coord_z, ws);
255 m_curve.mul(m_coord_z, T3, T4, ws);
256 }
void set_words(const word w[], size_t len)
Definition: bigint.h:547
BigInt & mod_sub(const BigInt &y, const BigInt &mod, secure_vector< word > &ws)
Definition: big_ops2.cpp:94
void clear()
Definition: bigint.h:379
void mul(BigInt &z, const BigInt &x, const BigInt &y, secure_vector< word > &ws) const
Definition: curve_gfp.h:175
void sqr(BigInt &z, const BigInt &x, secure_vector< word > &ws) const
Definition: curve_gfp.h:186
const BigInt & get_p() const
Definition: curve_gfp.h:134
void mult2(std::vector< BigInt > &workspace)
Definition: ec_point.cpp:278
bool is_zero() const
Definition: ec_point.h:183

References Botan::BigInt::clear(), Botan::CurveGFp::get_1_rep(), Botan::CurveGFp::get_p(), Botan::CurveGFp::get_ws_size(), Botan::BigInt::is_zero(), is_zero(), Botan::BigInt::mod_sub(), Botan::CurveGFp::mul(), mult2(), Botan::BigInt::set_words(), and Botan::CurveGFp::sqr().

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

254 {
255 BOTAN_ASSERT_NOMSG(m_curve == other.m_curve);
256 BOTAN_DEBUG_ASSERT(other.is_affine());
257
258 const size_t p_words = m_curve.get_p_words();
259 add_affine(other.m_coord_x.data(), std::min(p_words, other.m_coord_x.size()),
260 other.m_coord_y.data(), std::min(p_words, other.m_coord_y.size()),
261 workspace);
262 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition: assert.h:67
#define BOTAN_DEBUG_ASSERT(expr)
Definition: assert.h:122
void add_affine(const EC_Point &other, std::vector< BigInt > &workspace)
Definition: ec_point.h:253

References BOTAN_ASSERT_NOMSG, BOTAN_DEBUG_ASSERT, Botan::BigInt::data(), 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 89 of file ec_point.cpp.

92 {
93 if(all_zeros(x_words, x_size) & all_zeros(y_words, y_size))
94 {
95 return;
96 }
97
98 if(is_zero())
99 {
100 m_coord_x.set_words(x_words, x_size);
101 m_coord_y.set_words(y_words, y_size);
102 m_coord_z = m_curve.get_1_rep();
103 return;
104 }
105
106 resize_ws(ws_bn, m_curve.get_ws_size());
107
108 secure_vector<word>& ws = ws_bn[0].get_word_vector();
109 secure_vector<word>& sub_ws = ws_bn[1].get_word_vector();
110
111 BigInt& T0 = ws_bn[2];
112 BigInt& T1 = ws_bn[3];
113 BigInt& T2 = ws_bn[4];
114 BigInt& T3 = ws_bn[5];
115 BigInt& T4 = ws_bn[6];
116
117 /*
118 https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-1998-cmo-2
119 simplified with Z2 = 1
120 */
121
122 const BigInt& p = m_curve.get_p();
123
124 m_curve.sqr(T3, m_coord_z, ws); // z1^2
125 m_curve.mul(T4, x_words, x_size, T3, ws); // x2*z1^2
126
127 m_curve.mul(T2, m_coord_z, T3, ws); // z1^3
128 m_curve.mul(T0, y_words, y_size, T2, ws); // y2*z1^3
129
130 T4.mod_sub(m_coord_x, p, sub_ws); // x2*z1^2 - x1*z2^2
131
132 T0.mod_sub(m_coord_y, p, sub_ws);
133
134 if(T4.is_zero())
135 {
136 if(T0.is_zero())
137 {
138 mult2(ws_bn);
139 return;
140 }
141
142 // setting to zero:
143 m_coord_x.clear();
144 m_coord_y = m_curve.get_1_rep();
145 m_coord_z.clear();
146 return;
147 }
148
149 m_curve.sqr(T2, T4, ws);
150
151 m_curve.mul(T3, m_coord_x, T2, ws);
152
153 m_curve.mul(T1, T2, T4, ws);
154
155 m_curve.sqr(m_coord_x, T0, ws);
156 m_coord_x.mod_sub(T1, p, sub_ws);
157
158 m_coord_x.mod_sub(T3, p, sub_ws);
159 m_coord_x.mod_sub(T3, p, sub_ws);
160
161 T3.mod_sub(m_coord_x, p, sub_ws);
162
163 m_curve.mul(T2, T0, T3, ws);
164 m_curve.mul(T0, m_coord_y, T1, ws);
165 T2.mod_sub(T0, p, sub_ws);
166 m_coord_y.swap(T2);
167
168 m_curve.mul(T0, m_coord_z, T4, ws);
169 m_coord_z.swap(T0);
170 }
void swap(BigInt &other)
Definition: bigint.h:174

References Botan::BigInt::clear(), Botan::CurveGFp::get_1_rep(), Botan::CurveGFp::get_p(), Botan::CurveGFp::get_ws_size(), Botan::BigInt::is_zero(), is_zero(), Botan::BigInt::mod_sub(), Botan::CurveGFp::mul(), mult2(), Botan::BigInt::set_words(), Botan::CurveGFp::sqr(), 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 308 of file ec_point.h.

309 {
310 EC_Point x = (*this);
311 x.mult2(workspace);
312 return x;
313 }
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 600 of file ec_point.cpp.

601 {
602 if(is_zero())
603 return std::vector<uint8_t>(1); // single 0 byte
604
605 const size_t p_bytes = m_curve.get_p().bytes();
606
607 const BigInt x = get_affine_x();
608 const BigInt y = get_affine_y();
609
610 std::vector<uint8_t> result;
611
613 {
614 result.resize(1 + 2*p_bytes);
615 result[0] = 0x04;
616 BigInt::encode_1363(&result[1], p_bytes, x);
617 BigInt::encode_1363(&result[1+p_bytes], p_bytes, y);
618 }
619 else if(format == EC_Point_Format::Compressed)
620 {
621 result.resize(1 + p_bytes);
622 result[0] = 0x02 | static_cast<uint8_t>(y.get_bit(0));
623 BigInt::encode_1363(&result[1], p_bytes, x);
624 }
625 else if(format == EC_Point_Format::Hybrid)
626 {
627 result.resize(1 + 2*p_bytes);
628 result[0] = 0x06 | static_cast<uint8_t>(y.get_bit(0));
629 BigInt::encode_1363(&result[1], p_bytes, x);
630 BigInt::encode_1363(&result[1+p_bytes], p_bytes, y);
631 }
632 else
633 throw Invalid_Argument("EC2OSP illegal point encoding");
634
635 return result;
636 }
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:107
size_t bytes() const
Definition: bigint.cpp:297
BigInt get_affine_x() const
Definition: ec_point.cpp:504
BigInt get_affine_y() const
Definition: ec_point.cpp:523

References Botan::BigInt::bytes(), Botan::Compressed, Botan::BigInt::encode_1363(), get_affine_x(), get_affine_y(), Botan::CurveGFp::get_p(), Botan::Hybrid, is_zero(), Botan::Uncompressed, and y.

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

◆ force_affine()

void Botan::EC_Point::force_affine ( )

Force this point to affine coordinates

Definition at line 484 of file ec_point.cpp.

485 {
486 if(is_zero())
487 throw Invalid_State("Cannot convert zero ECC point to affine");
488
489 secure_vector<word> ws;
490
491 const BigInt z_inv = m_curve.invert_element(m_coord_z, ws);
492 const BigInt z2_inv = m_curve.sqr_to_tmp(z_inv, ws);
493 const BigInt z3_inv = m_curve.mul_to_tmp(z_inv, z2_inv, ws);
494 m_coord_x = m_curve.mul_to_tmp(m_coord_x, z2_inv, ws);
495 m_coord_y = m_curve.mul_to_tmp(m_coord_y, z3_inv, ws);
496 m_coord_z = m_curve.get_1_rep();
497 }
BigInt invert_element(const BigInt &x, secure_vector< word > &ws) const
Definition: curve_gfp.h:151
BigInt sqr_to_tmp(const BigInt &x, secure_vector< word > &ws) const
Definition: curve_gfp.h:213
BigInt mul_to_tmp(const BigInt &x, const BigInt &y, secure_vector< word > &ws) const
Definition: curve_gfp.h:206

References Botan::CurveGFp::get_1_rep(), Botan::CurveGFp::invert_element(), is_zero(), Botan::CurveGFp::mul_to_tmp(), and Botan::CurveGFp::sqr_to_tmp().

◆ force_all_affine()

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

Force all points on the list to affine coordinates

Definition at line 419 of file ec_point.cpp.

421 {
422 if(points.size() <= 1)
423 {
424 for(auto& point : points)
425 point.force_affine();
426 return;
427 }
428
429 for(auto& point : points)
430 {
431 if(point.is_zero())
432 throw Invalid_State("Cannot convert zero ECC point to affine");
433 }
434
435 /*
436 For >= 2 points use Montgomery's trick
437
438 See Algorithm 2.26 in "Guide to Elliptic Curve Cryptography"
439 (Hankerson, Menezes, Vanstone)
440
441 TODO is it really necessary to save all k points in c?
442 */
443
444 const CurveGFp& curve = points[0].m_curve;
445 const BigInt& rep_1 = curve.get_1_rep();
446
447 if(ws.size() < curve.get_ws_size())
448 ws.resize(curve.get_ws_size());
449
450 std::vector<BigInt> c(points.size());
451 c[0] = points[0].m_coord_z;
452
453 for(size_t i = 1; i != points.size(); ++i)
454 {
455 curve.mul(c[i], c[i-1], points[i].m_coord_z, ws);
456 }
457
458 BigInt s_inv = curve.invert_element(c[c.size()-1], ws);
459
460 BigInt z_inv, z2_inv, z3_inv;
461
462 for(size_t i = points.size() - 1; i != 0; i--)
463 {
464 EC_Point& point = points[i];
465
466 curve.mul(z_inv, s_inv, c[i-1], ws);
467
468 s_inv = curve.mul_to_tmp(s_inv, point.m_coord_z, ws);
469
470 curve.sqr(z2_inv, z_inv, ws);
471 curve.mul(z3_inv, z2_inv, z_inv, ws);
472 point.m_coord_x = curve.mul_to_tmp(point.m_coord_x, z2_inv, ws);
473 point.m_coord_y = curve.mul_to_tmp(point.m_coord_y, z3_inv, ws);
474 point.m_coord_z = rep_1;
475 }
476
477 curve.sqr(z2_inv, s_inv, ws);
478 curve.mul(z3_inv, z2_inv, s_inv, ws);
479 points[0].m_coord_x = curve.mul_to_tmp(points[0].m_coord_x, z2_inv, ws);
480 points[0].m_coord_y = curve.mul_to_tmp(points[0].m_coord_y, z3_inv, ws);
481 points[0].m_coord_z = rep_1;
482 }

References Botan::CurveGFp::get_1_rep(), Botan::CurveGFp::get_ws_size(), Botan::CurveGFp::invert_element(), Botan::CurveGFp::mul(), Botan::CurveGFp::mul_to_tmp(), Botan::BigInt::resize(), and Botan::CurveGFp::sqr().

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 504 of file ec_point.cpp.

505 {
506 if(is_zero())
507 throw Invalid_State("Cannot convert zero point to affine");
508
509 secure_vector<word> monty_ws;
510
511 if(is_affine())
512 return m_curve.from_rep_to_tmp(m_coord_x, monty_ws);
513
514 BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws);
515 z2 = m_curve.invert_element(z2, monty_ws);
516
517 BigInt r;
518 m_curve.mul(r, m_coord_x, z2, monty_ws);
519 m_curve.from_rep(r, monty_ws);
520 return r;
521 }
BigInt from_rep_to_tmp(const BigInt &x, secure_vector< word > &ws) const
Definition: curve_gfp.h:166
void from_rep(BigInt &x, secure_vector< word > &ws) const
Definition: curve_gfp.h:161
bool is_affine() const
Definition: ec_point.cpp:499

References Botan::CurveGFp::from_rep(), Botan::CurveGFp::from_rep_to_tmp(), Botan::CurveGFp::invert_element(), is_affine(), is_zero(), Botan::CurveGFp::mul(), and Botan::CurveGFp::sqr_to_tmp().

Referenced by Botan::EC_Group::blinded_base_point_multiply_x(), encode(), operator==(), Botan::GOST_3410_PublicKey::public_key_bits(), and Botan::sm2_compute_za().

◆ get_affine_y()

BigInt Botan::EC_Point::get_affine_y ( ) const

get affine y coordinate

Returns
affine y coordinate

Definition at line 523 of file ec_point.cpp.

524 {
525 if(is_zero())
526 throw Invalid_State("Cannot convert zero point to affine");
527
528 secure_vector<word> monty_ws;
529
530 if(is_affine())
531 return m_curve.from_rep_to_tmp(m_coord_y, monty_ws);
532
533 const BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws);
534 const BigInt z3 = m_curve.mul_to_tmp(m_coord_z, z2, monty_ws);
535 const BigInt z3_inv = m_curve.invert_element(z3, monty_ws);
536
537 BigInt r;
538 m_curve.mul(r, m_coord_y, z3_inv, monty_ws);
539 m_curve.from_rep(r, monty_ws);
540 return r;
541 }

References Botan::CurveGFp::from_rep(), Botan::CurveGFp::from_rep_to_tmp(), Botan::CurveGFp::invert_element(), is_affine(), is_zero(), Botan::CurveGFp::mul(), Botan::CurveGFp::mul_to_tmp(), and Botan::CurveGFp::sqr_to_tmp().

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

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

326{ return m_curve; }

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

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

143{ return m_coord_x; }

Referenced by Botan::EC_PublicKey::get_int_field().

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

150{ return m_coord_y; }

Referenced by Botan::EC_PublicKey::get_int_field().

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

157{ return m_coord_z; }

◆ is_affine()

bool Botan::EC_Point::is_affine ( ) const

Definition at line 499 of file ec_point.cpp.

500 {
501 return m_curve.is_one(m_coord_z);
502 }
bool is_one(const BigInt &x) const
Definition: curve_gfp.h:149

References Botan::CurveGFp::is_one().

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

183{ return m_coord_z.is_zero(); }
bool is_zero() const
Definition: bigint.h:434

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

◆ mult2()

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

Point doubling

Parameters
workspacetemp space, at least WORKSPACE_SIZE elements

Definition at line 278 of file ec_point.cpp.

279 {
280 if(is_zero())
281 return;
282
283 if(m_coord_y.is_zero())
284 {
285 *this = EC_Point(m_curve); // setting myself to zero
286 return;
287 }
288
289 resize_ws(ws_bn, m_curve.get_ws_size());
290
291 secure_vector<word>& ws = ws_bn[0].get_word_vector();
292 secure_vector<word>& sub_ws = ws_bn[1].get_word_vector();
293
294 BigInt& T0 = ws_bn[2];
295 BigInt& T1 = ws_bn[3];
296 BigInt& T2 = ws_bn[4];
297 BigInt& T3 = ws_bn[5];
298 BigInt& T4 = ws_bn[6];
299
300 /*
301 https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-1986-cc
302 */
303 const BigInt& p = m_curve.get_p();
304
305 m_curve.sqr(T0, m_coord_y, ws);
306
307 m_curve.mul(T1, m_coord_x, T0, ws);
308 T1.mod_mul(4, p, sub_ws);
309
310 if(m_curve.a_is_zero())
311 {
312 // if a == 0 then 3*x^2 + a*z^4 is just 3*x^2
313 m_curve.sqr(T4, m_coord_x, ws); // x^2
314 T4.mod_mul(3, p, sub_ws); // 3*x^2
315 }
316 else if(m_curve.a_is_minus_3())
317 {
318 /*
319 if a == -3 then
320 3*x^2 + a*z^4 == 3*x^2 - 3*z^4 == 3*(x^2-z^4) == 3*(x-z^2)*(x+z^2)
321 */
322 m_curve.sqr(T3, m_coord_z, ws); // z^2
323
324 // (x-z^2)
325 T2 = m_coord_x;
326 T2.mod_sub(T3, p, sub_ws);
327
328 // (x+z^2)
329 T3.mod_add(m_coord_x, p, sub_ws);
330
331 m_curve.mul(T4, T2, T3, ws); // (x-z^2)*(x+z^2)
332
333 T4.mod_mul(3, p, sub_ws); // 3*(x-z^2)*(x+z^2)
334 }
335 else
336 {
337 m_curve.sqr(T3, m_coord_z, ws); // z^2
338 m_curve.sqr(T4, T3, ws); // z^4
339 m_curve.mul(T3, m_curve.get_a_rep(), T4, ws); // a*z^4
340
341 m_curve.sqr(T4, m_coord_x, ws); // x^2
342 T4.mod_mul(3, p, sub_ws);
343 T4.mod_add(T3, p, sub_ws); // 3*x^2 + a*z^4
344 }
345
346 m_curve.sqr(T2, T4, ws);
347 T2.mod_sub(T1, p, sub_ws);
348 T2.mod_sub(T1, p, sub_ws);
349
350 m_curve.sqr(T3, T0, ws);
351 T3.mod_mul(8, p, sub_ws);
352
353 T1.mod_sub(T2, p, sub_ws);
354
355 m_curve.mul(T0, T4, T1, ws);
356 T0.mod_sub(T3, p, sub_ws);
357
358 m_coord_x.swap(T2);
359
360 m_curve.mul(T2, m_coord_y, m_coord_z, ws);
361 T2.mod_mul(2, p, sub_ws);
362
363 m_coord_y.swap(T0);
364 m_coord_z.swap(T2);
365 }
BigInt & mod_add(const BigInt &y, const BigInt &mod, secure_vector< word > &ws)
Definition: big_ops2.cpp:50
bool a_is_minus_3() const
Definition: curve_gfp.h:146
const BigInt & get_a_rep() const
Definition: curve_gfp.h:140
bool a_is_zero() const
Definition: curve_gfp.h:147

References Botan::CurveGFp::a_is_minus_3(), Botan::CurveGFp::a_is_zero(), EC_Point(), Botan::CurveGFp::get_a_rep(), Botan::CurveGFp::get_p(), Botan::CurveGFp::get_ws_size(), Botan::BigInt::is_zero(), is_zero(), Botan::BigInt::mod_add(), Botan::BigInt::mod_mul(), Botan::BigInt::mod_sub(), Botan::CurveGFp::mul(), Botan::CurveGFp::sqr(), 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(), mult2i(), and Botan::operator*().

◆ 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 258 of file ec_point.cpp.

259 {
260 if(iterations == 0)
261 return;
262
263 if(m_coord_y.is_zero())
264 {
265 *this = EC_Point(m_curve); // setting myself to zero
266 return;
267 }
268
269 /*
270 TODO we can save 2 squarings per iteration by computing
271 a*Z^4 using values cached from previous iteration
272 */
273 for(size_t i = 0; i != iterations; ++i)
274 mult2(ws_bn);
275 }

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

120 {
121 if(!is_zero())
122 m_coord_y = m_curve.get_p() - m_coord_y;
123 return *this;
124 }

Referenced by Botan::EC_Point_Multi_Point_Precompute::multi_exp(), Botan::operator*(), and Botan::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 543 of file ec_point.cpp.

544 {
545 /*
546 Is the point still on the curve?? (If everything is correct, the
547 point is always on its curve; then the function will return true.
548 If somehow the state is corrupted, which suggests a fault attack
549 (or internal computational error), then return false.
550 */
551 if(is_zero())
552 return true;
553
554 secure_vector<word> monty_ws;
555
556 const BigInt y2 = m_curve.from_rep_to_tmp(m_curve.sqr_to_tmp(m_coord_y, monty_ws), monty_ws);
557 const BigInt x3 = m_curve.mul_to_tmp(m_coord_x, m_curve.sqr_to_tmp(m_coord_x, monty_ws), monty_ws);
558 const BigInt ax = m_curve.mul_to_tmp(m_coord_x, m_curve.get_a_rep(), monty_ws);
559 const BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws);
560
561 if(m_coord_z == z2) // Is z equal to 1 (in Montgomery form)?
562 {
563 if(y2 != m_curve.from_rep_to_tmp(x3 + ax + m_curve.get_b_rep(), monty_ws))
564 return false;
565 }
566
567 const BigInt z3 = m_curve.mul_to_tmp(m_coord_z, z2, monty_ws);
568 const BigInt ax_z4 = m_curve.mul_to_tmp(ax, m_curve.sqr_to_tmp(z2, monty_ws), monty_ws);
569 const BigInt b_z6 = m_curve.mul_to_tmp(m_curve.get_b_rep(), m_curve.sqr_to_tmp(z3, monty_ws), monty_ws);
570
571 if(y2 != m_curve.from_rep_to_tmp(x3 + ax_z4 + b_z6, monty_ws))
572 return false;
573
574 return true;
575 }
const BigInt & get_b_rep() const
Definition: curve_gfp.h:142

References Botan::CurveGFp::from_rep_to_tmp(), Botan::CurveGFp::get_a_rep(), Botan::CurveGFp::get_b_rep(), is_zero(), Botan::CurveGFp::mul_to_tmp(), and Botan::CurveGFp::sqr_to_tmp().

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

◆ 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 387 of file ec_point.cpp.

388 {
389 *this = scalar * *this;
390 return *this;
391 }

◆ 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 368 of file ec_point.cpp.

369 {
370 std::vector<BigInt> ws(EC_Point::WORKSPACE_SIZE);
371 add(rhs, ws);
372 return *this;
373 }

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 375 of file ec_point.cpp.

376 {
377 EC_Point minus_rhs = EC_Point(rhs).negate();
378
379 if(is_zero())
380 *this = minus_rhs;
381 else
382 *this += minus_rhs;
383
384 return *this;
385 }

References EC_Point(), and is_zero().

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

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

◆ operator==()

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

Equality operator

Definition at line 586 of file ec_point.cpp.

587 {
588 if(m_curve != other.m_curve)
589 return false;
590
591 // If this is zero, only equal if other is also zero
592 if(is_zero())
593 return other.is_zero();
594
595 return (get_affine_x() == other.get_affine_x() &&
596 get_affine_y() == other.get_affine_y());
597 }

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

297 {
298 EC_Point x = (*this);
299 x.add(other, workspace);
300 return x;
301 }

References add().

Referenced by 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 42 of file ec_point.cpp.

43 {
44 secure_vector<word> ws(m_curve.get_ws_size());
45 randomize_repr(rng, ws);
46 }
void randomize_repr(RandomNumberGenerator &rng)
Definition: ec_point.cpp:42

References Botan::CurveGFp::get_ws_size(), and randomize_repr().

Referenced by 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 48 of file ec_point.cpp.

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

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

◆ swap()

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

swaps the states of *this and other, does not throw!

Parameters
otherthe object to swap values with

Definition at line 578 of file ec_point.cpp.

579 {
580 m_curve.swap(other.m_curve);
581 m_coord_x.swap(other.m_coord_x);
582 m_coord_y.swap(other.m_coord_y);
583 m_coord_z.swap(other.m_coord_z);
584 }
void swap(CurveGFp &other)
Definition: curve_gfp.h:220

References Botan::BigInt::swap(), and Botan::CurveGFp::swap().

Referenced by Botan::EC_Point_Base_Point_Precompute::EC_Point_Base_Point_Precompute(), and std::swap< Botan::EC_Point >().

◆ swap_coords()

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

Definition at line 159 of file ec_point.h.

160 {
161 m_coord_x.swap(new_x);
162 m_coord_y.swap(new_y);
163 m_coord_z.swap(new_z);
164 }

◆ zero()

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

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