10#include <botan/ec_point.h>
11#include <botan/numthry.h>
13#include <botan/internal/ct_utils.h>
20 m_coord_y(curve.get_1_rep()),
30 m_coord_z(m_curve.get_1_rep())
32 if(x < 0 || x >= curve.
get_p())
34 if(y < 0 || y >= curve.
get_p())
38 m_curve.
to_rep(m_coord_x, monty_ws);
39 m_curve.
to_rep(m_coord_y, monty_ws);
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);
69inline void resize_ws(std::vector<BigInt>& ws_bn,
size_t cap_size)
72 "Expected size for EC_Point workspace");
75 if(ws.size() < cap_size)
76 ws.get_word_vector().resize(cap_size);
79inline word all_zeros(
const word x[],
size_t len)
82 for(
size_t i = 0; i != len; ++i)
90 const word y_words[],
size_t y_size,
91 std::vector<BigInt>& ws_bn)
93 if(all_zeros(x_words, x_size) & all_zeros(y_words, y_size))
124 m_curve.
sqr(T3, m_coord_z, ws);
125 m_curve.
mul(T4, x_words, x_size, T3, ws);
127 m_curve.
mul(T2, m_coord_z, T3, ws);
128 m_curve.
mul(T0, y_words, y_size, T2, ws);
130 T4.
mod_sub(m_coord_x, p, sub_ws);
132 T0.
mod_sub(m_coord_y, p, sub_ws);
149 m_curve.
sqr(T2, T4, ws);
151 m_curve.
mul(T3, m_coord_x, T2, ws);
153 m_curve.
mul(T1, T2, T4, ws);
155 m_curve.
sqr(m_coord_x, T0, ws);
156 m_coord_x.
mod_sub(T1, p, sub_ws);
158 m_coord_x.
mod_sub(T3, p, sub_ws);
159 m_coord_x.
mod_sub(T3, p, sub_ws);
161 T3.
mod_sub(m_coord_x, p, sub_ws);
163 m_curve.
mul(T2, T0, T3, ws);
164 m_curve.
mul(T0, m_coord_y, T1, ws);
168 m_curve.
mul(T0, m_coord_z, T4, ws);
173 const word y_words[],
size_t y_size,
174 const word z_words[],
size_t z_size,
175 std::vector<BigInt>& ws_bn)
177 if(all_zeros(x_words, x_size) & all_zeros(z_words, z_size))
206 m_curve.
sqr(T0, z_words, z_size, ws);
207 m_curve.
mul(T1, m_coord_x, T0, ws);
208 m_curve.
mul(T3, z_words, z_size, T0, ws);
209 m_curve.
mul(T2, m_coord_y, T3, ws);
211 m_curve.
sqr(T3, m_coord_z, ws);
212 m_curve.
mul(T4, x_words, x_size, T3, ws);
214 m_curve.
mul(T5, m_coord_z, T3, ws);
215 m_curve.
mul(T0, y_words, y_size, T5, ws);
236 m_curve.
sqr(T5, T4, ws);
238 m_curve.
mul(T3, T1, T5, ws);
240 m_curve.
mul(T1, T5, T4, ws);
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);
247 T3.
mod_sub(m_coord_x, p, sub_ws);
249 m_curve.
mul(m_coord_y, T0, T3, ws);
250 m_curve.
mul(T3, T2, T1, ws);
252 m_coord_y.
mod_sub(T3, p, sub_ws);
254 m_curve.
mul(T3, z_words, z_size, m_coord_z, ws);
255 m_curve.
mul(m_coord_z, T3, T4, ws);
273 for(
size_t i = 0; i != iterations; ++i)
305 m_curve.
sqr(T0, m_coord_y, ws);
307 m_curve.
mul(T1, m_coord_x, T0, ws);
313 m_curve.
sqr(T4, m_coord_x, ws);
322 m_curve.
sqr(T3, m_coord_z, ws);
329 T3.
mod_add(m_coord_x, p, sub_ws);
331 m_curve.
mul(T4, T2, T3, ws);
337 m_curve.
sqr(T3, m_coord_z, ws);
338 m_curve.
sqr(T4, T3, ws);
341 m_curve.
sqr(T4, m_coord_x, ws);
346 m_curve.
sqr(T2, T4, ws);
350 m_curve.
sqr(T3, T0, ws);
355 m_curve.
mul(T0, T4, T1, ws);
360 m_curve.
mul(T2, m_coord_y, m_coord_z, ws);
389 *
this = scalar * *
this;
397 const size_t scalar_bits = scalar.
bits();
403 for(
size_t i = scalar_bits; i > 0; i--)
405 const size_t b = scalar.
get_bit(i - 1);
406 R[b ^ 1].
add(R[b], ws);
422 if(points.size() <= 1)
424 for(
auto& point : points)
425 point.force_affine();
429 for(
auto& point : points)
432 throw Invalid_State(
"Cannot convert zero ECC point to affine");
444 const CurveGFp& curve = points[0].m_curve;
450 std::vector<BigInt> c(points.size());
451 c[0] = points[0].m_coord_z;
453 for(
size_t i = 1; i != points.size(); ++i)
455 curve.
mul(c[i], c[i-1], points[i].m_coord_z, ws);
460 BigInt z_inv, z2_inv, z3_inv;
462 for(
size_t i = points.size() - 1; i != 0; i--)
466 curve.
mul(z_inv, s_inv, c[i-1], ws);
468 s_inv = curve.
mul_to_tmp(s_inv, point.m_coord_z, ws);
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;
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;
487 throw Invalid_State(
"Cannot convert zero ECC point to affine");
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);
501 return m_curve.
is_one(m_coord_z);
518 m_curve.
mul(r, m_coord_x, z2, monty_ws);
538 m_curve.
mul(r, m_coord_y, z3_inv, monty_ws);
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);
588 if(m_curve != other.m_curve)
603 return std::vector<uint8_t>(1);
605 const size_t p_bytes = m_curve.
get_p().
bytes();
610 std::vector<uint8_t> result;
614 result.resize(1 + 2*p_bytes);
621 result.resize(1 + p_bytes);
622 result[0] = 0x02 |
static_cast<uint8_t
>(
y.get_bit(0));
627 result.resize(1 + 2*p_bytes);
628 result[0] = 0x06 |
static_cast<uint8_t
>(
y.get_bit(0));
640BigInt decompress_point(
bool yMod2,
675 EC_Point point(curve, xy.first, xy.second);
678 throw Decoding_Error(
"OS2ECP: Decoded point was not on the curve");
683std::pair<BigInt, BigInt>
OS2ECP(
const uint8_t data[],
size_t data_len,
691 const uint8_t pc = data[0];
695 if(pc == 2 || pc == 3)
700 const bool y_mod_2 = ((pc & 0x01) == 1);
701 y = decompress_point(y_mod_2, x, curve_p, curve_a, curve_b);
705 const size_t l = (data_len - 1) / 2;
711 else if(pc == 6 || pc == 7)
713 const size_t l = (data_len - 1) / 2;
719 const bool y_mod_2 = ((pc & 0x01) == 1);
721 if(decompress_point(y_mod_2, x, curve_p, curve_a, curve_b) !=
y)
725 throw Invalid_Argument(
"OS2ECP: Unknown format type " + std::to_string(pc));
727 return std::make_pair(x,
y);
#define BOTAN_DEBUG_ASSERT(expr)
#define BOTAN_ASSERT(expr, assertion_made)
BigInt & mod_mul(uint8_t y, const BigInt &mod, secure_vector< word > &ws)
static BigInt decode(const uint8_t buf[], size_t length)
static BigInt random_integer(RandomNumberGenerator &rng, const BigInt &min, const BigInt &max)
void set_words(const word w[], size_t len)
BigInt & mod_add(const BigInt &y, const BigInt &mod, secure_vector< word > &ws)
BigInt & mod_sub(const BigInt &y, const BigInt &mod, secure_vector< word > &ws)
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
bool get_bit(size_t n) const
static Mask< T > is_zero(T x)
bool a_is_minus_3() const
void mul(BigInt &z, const BigInt &x, const BigInt &y, secure_vector< word > &ws) const
size_t get_ws_size() const
BigInt invert_element(const BigInt &x, secure_vector< word > &ws) const
const BigInt & get_1_rep() const
const BigInt & get_b_rep() const
bool is_one(const BigInt &x) const
void sqr(BigInt &z, const BigInt &x, secure_vector< word > &ws) const
void swap(CurveGFp &other)
const BigInt & get_a_rep() const
BigInt from_rep_to_tmp(const BigInt &x, secure_vector< word > &ws) const
const BigInt & get_a() const
void to_rep(BigInt &x, secure_vector< word > &ws) const
const BigInt & get_p() const
BigInt sqr_to_tmp(const BigInt &x, secure_vector< word > &ws) const
const BigInt & get_b() const
void from_rep(BigInt &x, secure_vector< word > &ws) const
BigInt mul_to_tmp(const BigInt &x, const BigInt &y, secure_vector< word > &ws) const
void swap(EC_Point &other)
void randomize_repr(RandomNumberGenerator &rng)
BigInt get_affine_x() const
void add(const EC_Point &other, std::vector< BigInt > &workspace)
void add_affine(const EC_Point &other, std::vector< BigInt > &workspace)
void mult2(std::vector< BigInt > &workspace)
void mult2i(size_t i, std::vector< BigInt > &workspace)
EC_Point & operator-=(const EC_Point &rhs)
bool on_the_curve() const
EC_Point & operator+=(const EC_Point &rhs)
bool operator==(const EC_Point &other) const
BigInt get_affine_y() const
EC_Point & operator*=(const BigInt &scalar)
static void force_all_affine(std::vector< EC_Point > &points, secure_vector< word > &ws)
std::vector< uint8_t > encode(EC_Point_Format format) const
BigInt operator*(const BigInt &x, const BigInt &y)
EC_Point OS2ECP(const uint8_t data[], size_t data_len, const CurveGFp &curve)
BigInt sqrt_modulo_prime(const BigInt &a, const BigInt &p)
std::vector< T, secure_allocator< T > > secure_vector