Botan 3.6.1
Crypto and TLS for C&
ec_point.h
Go to the documentation of this file.
1/*
2* Point arithmetic on elliptic curves over GF(p)
3*
4* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke
5* 2008-2011,2014,2015 Jack Lloyd
6*
7* Botan is released under the Simplified BSD License (see license.txt)
8*/
9
10#ifndef BOTAN_EC_POINT_H_
11#define BOTAN_EC_POINT_H_
12
13#include <botan/curve_gfp.h>
14#include <botan/exceptn.h>
15#include <vector>
16
17namespace Botan {
18
19enum class EC_Point_Format {
20 Uncompressed = 0,
21 Compressed = 1,
22
23 UNCOMPRESSED BOTAN_DEPRECATED("Use EC_Point_Format::Uncompressed") = Uncompressed,
24 COMPRESSED BOTAN_DEPRECATED("Use EC_Point_Format::Compressed") = Compressed,
25
26 Hybrid BOTAN_DEPRECATED("Hybrid point encoding is deprecated") = 2,
27 HYBRID BOTAN_DEPRECATED("Hybrid point encoding is deprecated") = 2
28};
29
30/**
31* Deprecated elliptic curve type
32*
33* Use EC_AffinePoint in new code
34*
35* This type will be removed/hidden in Botan4
36*/
38 public:
42
44 using enum EC_Point_Format;
45
46 enum { WORKSPACE_SIZE = 8 };
47
48 /**
49 * Construct an uninitialized EC_Point
50 */
51 EC_Point() = default;
52
53 /**
54 * Construct the zero point
55 * @param curve The base curve
56 */
57 explicit EC_Point(const CurveGFp& curve);
58
59 /**
60 * Copy constructor
61 */
62 EC_Point(const EC_Point&) = default;
63
64 /**
65 * Move Constructor
66 */
67 EC_Point(EC_Point&& other) { this->swap(other); }
68
69 /**
70 * Standard Assignment
71 */
72 EC_Point& operator=(const EC_Point&) = default;
73
74 /**
75 * Move Assignment
76 */
78 if(this != &other) {
79 this->swap(other);
80 }
81 return (*this);
82 }
83
84 /**
85 * Point multiplication operator
86 *
87 * Simple unblinded Montgomery ladder
88 *
89 * Warning: prefer the functions on EC_Group such as
90 * blinded_var_point_multiply
91 *
92 * @param scalar the scalar value
93 * @return *this multiplied by the scalar value
94 */
95 EC_Point mul(const BigInt& scalar) const;
96
97 /**
98 * Construct a point from its affine coordinates
99 * Prefer EC_Group::point(x,y) for this operation.
100 * @param curve the base curve
101 * @param x affine x coordinate
102 * @param y affine y coordinate
103 */
104 EC_Point(const CurveGFp& curve, BigInt x, BigInt y);
105
106 /**
107 * EC2OSP - elliptic curve to octet string primitive
108 * @param format which format to encode using
109 */
110 std::vector<uint8_t> encode(EC_Point_Format format) const;
111
112 /**
113 * += Operator
114 * @param rhs the EC_Point to add to the local value
115 * @result resulting EC_Point
116 */
117 EC_Point& operator+=(const EC_Point& rhs);
118
119 /**
120 * -= Operator
121 * @param rhs the EC_Point to subtract from the local value
122 * @result resulting EC_Point
123 */
124 EC_Point& operator-=(const EC_Point& rhs);
125
126 /**
127 * *= Operator
128 * @param scalar the EC_Point to multiply with *this
129 * @result resulting EC_Point
130 */
131 EC_Point& operator*=(const BigInt& scalar);
132
133 /**
134 * Negate this point
135 * @return *this
136 */
138 if(!is_zero()) {
139 m_coord_y = m_curve.get_p() - m_coord_y;
140 }
141 return *this;
142 }
143
144 /**
145 * Force this point to affine coordinates
146 *
147 * Convert the point to its equivalent affine coordinates. Throws if this
148 * is the point at infinity.
149 */
150 void force_affine();
151
152 /**
153 * Force all points on the list to affine coordinates
154 *
155 * Force several points to be affine at once. Uses Montgomery's trick to
156 * reduce number of inversions required, so this is much faster than
157 * calling ``force_affine`` on each point in sequence.
158 */
159 static void force_all_affine(std::span<EC_Point> points, secure_vector<word>& ws);
160
161 bool is_affine() const;
162
163 /**
164 * Is this the point at infinity?
165 * @result true, if this point is at infinity, false otherwise.
166 */
167 bool is_zero() const { return m_coord_z.is_zero(); }
168
169 /**
170 * Checks whether the point is to be found on the underlying
171 * curve; used to prevent fault attacks.
172 * @return if the point is on the curve
173 */
174 bool on_the_curve() const;
175
176 /**
177 * Return the fixed length big endian encoding of x coordinate
178 */
179 secure_vector<uint8_t> x_bytes() const;
180
181 /**
182 * Return the fixed length big endian encoding of y coordinate
183 */
184 secure_vector<uint8_t> y_bytes() const;
185
186 /**
187 * Return the fixed length concatenation of the x and y coordinates
188 */
189 secure_vector<uint8_t> xy_bytes() const;
190
191 /**
192 * get affine x coordinate
193 * @result affine x coordinate
194 */
195 BigInt get_affine_x() const;
196
197 /**
198 * get affine y coordinate
199 * @result affine y coordinate
200 */
201 BigInt get_affine_y() const;
202
203 /**
204 * Return the zero (aka infinite) point associated with this curve
205 */
206 EC_Point zero() const { return EC_Point(m_curve); }
207
208 /**
209 * Randomize the point representation
210 * The actual value (get_affine_x, get_affine_y) does not change
211 */
212 void randomize_repr(RandomNumberGenerator& rng);
213
214 /**
215 * Equality operator
216 */
217 bool operator==(const EC_Point& other) const;
218
219 bool operator!=(const EC_Point& other) const = default;
220
221 /**
222 * swaps the states of *this and other
223 * @param other the object to swap values with
224 */
225 void swap(EC_Point& other) noexcept;
226
227#if defined(BOTAN_DISABLE_DEPRECATED_FEATURES)
228
229 private:
230 friend class EC_Mul2Table_Data_BN;
231#endif
232
233 /**
234 * Return the internal x coordinate
235 *
236 * Note this may be in Montgomery form
237 */
238 BOTAN_DEPRECATED("Use affine coordinates only") const BigInt& get_x() const { return m_coord_x; }
239
240 /**
241 * Return the internal y coordinate
242 *
243 * Note this may be in Montgomery form
244 */
245 BOTAN_DEPRECATED("Use affine coordinates only") const BigInt& get_y() const { return m_coord_y; }
246
247 /**
248 * Return the internal z coordinate
249 *
250 * Note this may be in Montgomery form
251 */
252 BOTAN_DEPRECATED("Use affine coordinates only") const BigInt& get_z() const { return m_coord_z; }
253
254 BOTAN_DEPRECATED("Deprecated no replacement")
255
256 void swap_coords(BigInt& new_x, BigInt& new_y, BigInt& new_z) {
257 m_coord_x.swap(new_x);
258 m_coord_y.swap(new_y);
259 m_coord_z.swap(new_z);
260 }
261
262 friend void swap(EC_Point& x, EC_Point& y) { x.swap(y); }
263
264 /**
265 * Randomize the point representation
266 * The actual value (get_affine_x, get_affine_y) does not change
267 */
268 void randomize_repr(RandomNumberGenerator& rng, secure_vector<word>& ws);
269
270 /**
271 * Point addition
272 * @param other the point to add to *this
273 * @param workspace temp space, at least WORKSPACE_SIZE elements
274 */
275 void add(const EC_Point& other, std::vector<BigInt>& workspace) {
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 }
288
289 /**
290 * Point addition. Array version.
291 *
292 * @param x_words the words of the x coordinate of the other point
293 * @param x_size size of x_words
294 * @param y_words the words of the y coordinate of the other point
295 * @param y_size size of y_words
296 * @param z_words the words of the z coordinate of the other point
297 * @param z_size size of z_words
298 * @param workspace temp space, at least WORKSPACE_SIZE elements
299 */
300 void add(const word x_words[],
301 size_t x_size,
302 const word y_words[],
303 size_t y_size,
304 const word z_words[],
305 size_t z_size,
306 std::vector<BigInt>& workspace);
307
308 /**
309 * Point addition - mixed J+A
310 *
311 * @warning This function assumes that @p other is affine, if this is not
312 * correct the result will be invalid.
313 *
314 * @param other affine point to add - assumed to be affine!
315 * @param workspace temp space, at least WORKSPACE_SIZE elements
316 */
317 void add_affine(const EC_Point& other, std::vector<BigInt>& workspace) {
318 BOTAN_ASSERT_NOMSG(m_curve == other.m_curve);
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 }
328
329 /**
330 * Point addition - mixed J+A. Array version.
331 *
332 * @param x_words the words of the x coordinate of the other point
333 * @param x_size size of x_words
334 * @param y_words the words of the y coordinate of the other point
335 * @param y_size size of y_words
336 * @param workspace temp space, at least WORKSPACE_SIZE elements
337 */
338 void add_affine(
339 const word x_words[], size_t x_size, const word y_words[], size_t y_size, std::vector<BigInt>& workspace);
340
341 /**
342 * Point doubling
343 * @param workspace temp space, at least WORKSPACE_SIZE elements
344 */
345 void mult2(std::vector<BigInt>& workspace);
346
347 /**
348 * Repeated point doubling
349 * @param i number of doublings to perform
350 * @param workspace temp space, at least WORKSPACE_SIZE elements
351 */
352 void mult2i(size_t i, std::vector<BigInt>& workspace);
353
354 /**
355 * Point addition
356 * @param other the point to add to *this
357 * @param workspace temp space, at least WORKSPACE_SIZE elements
358 * @return other plus *this
359 */
360 EC_Point plus(const EC_Point& other, std::vector<BigInt>& workspace) const {
361 EC_Point x = (*this);
362 x.add(other, workspace);
363 return x;
364 }
365
366 /**
367 * Point doubling
368 * @param workspace temp space, at least WORKSPACE_SIZE elements
369 * @return *this doubled
370 */
371 EC_Point double_of(std::vector<BigInt>& workspace) const {
372 EC_Point x = (*this);
373 x.mult2(workspace);
374 return x;
375 }
376
377 /**
378 * Return base curve of this point
379 * @result the curve over GF(p) of this point
380 *
381 * You should not need to use this
382 */
383 const CurveGFp& get_curve() const { return m_curve; }
384
385 private:
386 CurveGFp m_curve;
387 BigInt m_coord_x, m_coord_y, m_coord_z;
388};
389
390/**
391* ECC point multiexponentiation - not constant time!
392* @param p1 a point
393* @param z1 a scalar
394* @param p2 a point
395* @param z2 a scalar
396* @result (p1 * z1 + p2 * z2)
397*/
399EC_Point multi_exponentiate(const EC_Point& p1, const BigInt& z1, const EC_Point& p2, const BigInt& z2);
400
401// arithmetic operators
402inline EC_Point operator-(const EC_Point& lhs) {
403 return EC_Point(lhs).negate();
404}
405
406inline EC_Point operator+(const EC_Point& lhs, const EC_Point& rhs) {
407 EC_Point tmp(lhs);
408 return tmp += rhs;
409}
410
411inline EC_Point operator-(const EC_Point& lhs, const EC_Point& rhs) {
412 EC_Point tmp(lhs);
413 return tmp -= rhs;
414}
415
416inline EC_Point operator*(const EC_Point& point, const BigInt& scalar) {
417 return point.mul(scalar);
418}
419
420inline EC_Point operator*(const BigInt& scalar, const EC_Point& point) {
421 return point.mul(scalar);
422}
423
424/**
425* Perform point decoding
426* Use EC_Group::OS2ECP instead
427*/
428BOTAN_DEPRECATED("Use EC_Group::OS2ECP")
429EC_Point BOTAN_PUBLIC_API(2, 0) OS2ECP(const uint8_t data[], size_t data_len, const CurveGFp& curve);
430
431/**
432* Perform point decoding
433* Use EC_Group::OS2ECP instead
434*
435* @param data the encoded point
436* @param data_len length of data in bytes
437* @param curve_p the curve equation prime
438* @param curve_a the curve equation a parameter
439* @param curve_b the curve equation b parameter
440*/
441BOTAN_DEPRECATED("Use EC_Group::OS2ECP")
442std::pair<BigInt, BigInt> BOTAN_UNSTABLE_API
443 OS2ECP(const uint8_t data[], size_t data_len, const BigInt& curve_p, const BigInt& curve_a, const BigInt& curve_b);
444
445BOTAN_DEPRECATED("Use EC_Group::OS2ECP")
446EC_Point BOTAN_UNSTABLE_API OS2ECP(std::span<const uint8_t> data, const CurveGFp& curve);
447
448// The name used for this type in older versions
450
451} // namespace Botan
452
453#endif
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
#define BOTAN_DEBUG_ASSERT(expr)
Definition assert.h:98
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:29
void swap(BigInt &other)
Definition bigint.h:192
size_t size() const
Definition bigint.h:610
const word * _data() const
Definition bigint.h:936
EC_Point & negate()
Definition ec_point.h:137
void swap(EC_Point &other) noexcept
Definition ec_point.cpp:568
bool operator!=(const EC_Point &other) const =default
EC_Point & operator=(EC_Point &&other)
Definition ec_point.h:77
EC_Point plus(const EC_Point &other, std::vector< BigInt > &workspace) const
Definition ec_point.h:360
void add(const EC_Point &other, std::vector< BigInt > &workspace)
Definition ec_point.h:275
EC_Point(EC_Point &&other)
Definition ec_point.h:67
void add_affine(const EC_Point &other, std::vector< BigInt > &workspace)
Definition ec_point.h:317
void mult2(std::vector< BigInt > &workspace)
Definition ec_point.cpp:257
EC_Point double_of(std::vector< BigInt > &workspace) const
Definition ec_point.h:371
bool is_zero() const
Definition ec_point.h:167
EC_Point zero() const
Definition ec_point.h:206
bool is_affine() const
Definition ec_point.cpp:464
EC_Point mul(const BigInt &scalar) const
Definition ec_point.cpp:364
EC_Point(const EC_Point &)=default
const CurveGFp & get_curve() const
Definition ec_point.h:383
EC_Point & operator=(const EC_Point &)=default
friend void swap(EC_Point &x, EC_Point &y)
Definition ec_point.h:262
EC_Point()=default
EC_Point_Format Compression_Type
Definition ec_point.h:43
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition compiler.h:31
#define BOTAN_UNSTABLE_API
Definition compiler.h:44
#define BOTAN_DEPRECATED(msg)
Definition compiler.h:125
BigInt operator*(const BigInt &x, const BigInt &y)
Definition big_ops3.cpp:46
OctetString operator+(const OctetString &k1, const OctetString &k2)
Definition symkey.cpp:99
EC_Point multi_exponentiate(const EC_Point &p1, const BigInt &z1, const EC_Point &p2, const BigInt &z2)
Definition point_mul.cpp:30
BigInt operator-(const BigInt &x, const BigInt &y)
Definition bigint.h:1094
EC_Point_Format
Definition ec_point.h:19
bool operator==(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition alg_id.cpp:54
EC_Point OS2ECP(const uint8_t data[], size_t data_len, const CurveGFp &curve)
Definition ec_point.cpp:648
std::vector< T, Alloc > & operator+=(std::vector< T, Alloc > &out, const std::vector< T, Alloc2 > &in)
Definition secmem.h:80
constexpr auto operator-=(Strong< T1, Tags... > &a, T2 b)
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
constexpr auto operator*=(Strong< T1, Tags... > &a, T2 b)