Botan 3.4.0
Crypto and TLS for C&
Public Types | Public Member Functions | Static Public Member Functions | Friends | 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)
 

Friends

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

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

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

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

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

22 :
23 m_curve(curve), m_coord_x(x), m_coord_y(y), m_coord_z(m_curve.get_1_rep()) {
24 if(x < 0 || x >= curve.get_p()) {
25 throw Invalid_Argument("Invalid EC_Point affine x");
26 }
27 if(y < 0 || y >= curve.get_p()) {
28 throw Invalid_Argument("Invalid EC_Point affine y");
29 }
30
31 secure_vector<word> monty_ws(m_curve.get_ws_size());
32 m_curve.to_rep(m_coord_x, monty_ws);
33 m_curve.to_rep(m_coord_y, monty_ws);
34}
size_t get_ws_size() const
Definition curve_gfp.h:122
const BigInt & get_1_rep() const
Definition curve_gfp.h:128
void to_rep(BigInt &x, secure_vector< word > &ws) const
Definition curve_gfp.h:138

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

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

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

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

References Botan::CT::all_zeros(), 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 255 of file ec_point.h.

255 {
256 BOTAN_ASSERT_NOMSG(m_curve == other.m_curve);
257 BOTAN_DEBUG_ASSERT(other.is_affine());
258
259 const size_t p_words = m_curve.get_p_words();
260 add_affine(other.m_coord_x.data(),
261 std::min(p_words, other.m_coord_x.size()),
262 other.m_coord_y.data(),
263 std::min(p_words, other.m_coord_y.size()),
264 workspace);
265 }
#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:255

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

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

References Botan::CT::all_zeros(), 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 309 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 568 of file ec_point.cpp.

568 {
569 if(is_zero()) {
570 return std::vector<uint8_t>(1); // single 0 byte
571 }
572
573 const size_t p_bytes = m_curve.get_p().bytes();
574
575 const BigInt x = get_affine_x();
576 const BigInt y = get_affine_y();
577
578 std::vector<uint8_t> result;
579
580 if(format == EC_Point_Format::Uncompressed) {
581 result.resize(1 + 2 * p_bytes);
582 result[0] = 0x04;
583 BigInt::encode_1363(&result[1], p_bytes, x);
584 BigInt::encode_1363(&result[1 + p_bytes], p_bytes, y);
585 } else if(format == EC_Point_Format::Compressed) {
586 result.resize(1 + p_bytes);
587 result[0] = 0x02 | static_cast<uint8_t>(y.get_bit(0));
588 BigInt::encode_1363(&result[1], p_bytes, x);
589 } else if(format == EC_Point_Format::Hybrid) {
590 result.resize(1 + 2 * p_bytes);
591 result[0] = 0x06 | static_cast<uint8_t>(y.get_bit(0));
592 BigInt::encode_1363(&result[1], p_bytes, x);
593 BigInt::encode_1363(&result[1 + p_bytes], p_bytes, y);
594 } else {
595 throw Invalid_Argument("EC2OSP illegal point encoding");
596 }
597
598 return result;
599}
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition big_code.cpp:105
size_t bytes() const
Definition bigint.cpp:277
BigInt get_affine_x() const
Definition ec_point.cpp:469
BigInt get_affine_y() const
Definition ec_point.cpp:489

References Botan::BigInt::bytes(), Botan::Compressed, Botan::BigInt::encode_1363(), get_affine_x(), get_affine_y(), Botan::BigInt::get_bit(), Botan::CurveGFp::get_p(), Botan::Hybrid, is_zero(), 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::public_key_bits().

◆ force_affine()

void Botan::EC_Point::force_affine ( )

Force this point to affine coordinates

Definition at line 450 of file ec_point.cpp.

450 {
451 if(is_zero()) {
452 throw Invalid_State("Cannot convert zero ECC point to affine");
453 }
454
455 secure_vector<word> ws;
456
457 const BigInt z_inv = m_curve.invert_element(m_coord_z, ws);
458 const BigInt z2_inv = m_curve.sqr_to_tmp(z_inv, ws);
459 const BigInt z3_inv = m_curve.mul_to_tmp(z_inv, z2_inv, ws);
460 m_coord_x = m_curve.mul_to_tmp(m_coord_x, z2_inv, ws);
461 m_coord_y = m_curve.mul_to_tmp(m_coord_y, z3_inv, ws);
462 m_coord_z = m_curve.get_1_rep();
463}
BigInt invert_element(const BigInt &x, secure_vector< word > &ws) const
Definition curve_gfp.h:136
BigInt sqr_to_tmp(const BigInt &x, secure_vector< word > &ws) const
Definition curve_gfp.h:174
BigInt mul_to_tmp(const BigInt &x, const BigInt &y, secure_vector< word > &ws) const
Definition curve_gfp.h:168

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

Referenced by force_all_affine().

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

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

References force_affine(), 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 469 of file ec_point.cpp.

469 {
470 if(is_zero()) {
471 throw Invalid_State("Cannot convert zero point to affine");
472 }
473
474 secure_vector<word> monty_ws;
475
476 if(is_affine()) {
477 return m_curve.from_rep_to_tmp(m_coord_x, monty_ws);
478 }
479
480 BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws);
481 z2 = m_curve.invert_element(z2, monty_ws);
482
483 BigInt r;
484 m_curve.mul(r, m_coord_x, z2, monty_ws);
485 m_curve.from_rep(r, monty_ws);
486 return r;
487}
BigInt from_rep_to_tmp(const BigInt &x, secure_vector< word > &ws) const
Definition curve_gfp.h:142
void from_rep(BigInt &x, secure_vector< word > &ws) const
Definition curve_gfp.h:140
bool is_affine() const
Definition ec_point.cpp:465

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

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

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

140{ 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 147 of file ec_point.h.

147{ 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 154 of file ec_point.h.

154{ return m_coord_z; }

◆ is_affine()

bool Botan::EC_Point::is_affine ( ) const

Definition at line 465 of file ec_point.cpp.

465 {
466 return m_curve.is_one(m_coord_z);
467}
bool is_one(const BigInt &x) const
Definition curve_gfp.h:134

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

178{ return m_coord_z.is_zero(); }
bool is_zero() const
Definition bigint.h:428

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

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

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

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

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

116 {
117 if(!is_zero()) {
118 m_coord_y = m_curve.get_p() - m_coord_y;
119 }
120 return *this;
121 }

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

510 {
511 /*
512 Is the point still on the curve?? (If everything is correct, the
513 point is always on its curve; then the function will return true.
514 If somehow the state is corrupted, which suggests a fault attack
515 (or internal computational error), then return false.
516 */
517 if(is_zero()) {
518 return true;
519 }
520
521 secure_vector<word> monty_ws;
522
523 const BigInt y2 = m_curve.from_rep_to_tmp(m_curve.sqr_to_tmp(m_coord_y, monty_ws), monty_ws);
524 const BigInt x3 = m_curve.mul_to_tmp(m_coord_x, m_curve.sqr_to_tmp(m_coord_x, monty_ws), monty_ws);
525 const BigInt ax = m_curve.mul_to_tmp(m_coord_x, m_curve.get_a_rep(), monty_ws);
526 const BigInt z2 = m_curve.sqr_to_tmp(m_coord_z, monty_ws);
527
528 if(m_coord_z == z2) // Is z equal to 1 (in Montgomery form)?
529 {
530 if(y2 != m_curve.from_rep_to_tmp(x3 + ax + m_curve.get_b_rep(), monty_ws)) {
531 return false;
532 }
533 }
534
535 const BigInt z3 = m_curve.mul_to_tmp(m_coord_z, z2, monty_ws);
536 const BigInt ax_z4 = m_curve.mul_to_tmp(ax, m_curve.sqr_to_tmp(z2, monty_ws), monty_ws);
537 const BigInt b_z6 = m_curve.mul_to_tmp(m_curve.get_b_rep(), m_curve.sqr_to_tmp(z3, monty_ws), monty_ws);
538
539 if(y2 != m_curve.from_rep_to_tmp(x3 + ax_z4 + b_z6, monty_ws)) {
540 return false;
541 }
542
543 return true;
544}
const BigInt & get_b_rep() const
Definition curve_gfp.h:126

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

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

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

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

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

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

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

69 {
70 if(this != &other) {
71 this->swap(other);
72 }
73 return (*this);
74 }

◆ operator==()

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

Equality operator

Definition at line 554 of file ec_point.cpp.

554 {
555 if(m_curve != other.m_curve) {
556 return false;
557 }
558
559 // If this is zero, only equal if other is also zero
560 if(is_zero()) {
561 return other.is_zero();
562 }
563
564 return (get_affine_x() == other.get_affine_x() && get_affine_y() == other.get_affine_y());
565}

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

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

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

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

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

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

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

547 {
548 m_curve.swap(other.m_curve);
549 m_coord_x.swap(other.m_coord_x);
550 m_coord_y.swap(other.m_coord_y);
551 m_coord_z.swap(other.m_coord_z);
552}
void swap(CurveGFp &other)
Definition curve_gfp.h:180

References Botan::BigInt::swap(), and Botan::CurveGFp::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 156 of file ec_point.h.

156 {
157 m_coord_x.swap(new_x);
158 m_coord_y.swap(new_y);
159 m_coord_z.swap(new_z);
160 }

◆ zero()

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

Friends And Related Symbol Documentation

◆ swap

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

Definition at line 193 of file ec_point.h.

193{ x.swap(y); }

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