Botan 3.7.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,2024 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// TODO(Botan4) delete this header
14
15#include <botan/curve_gfp.h>
16#include <botan/ec_point_format.h>
17#include <botan/exceptn.h>
18#include <vector>
19
20namespace Botan {
21
22/**
23* Deprecated elliptic curve type
24*
25* Use EC_AffinePoint in new code; this type is no longer used internally at all
26* except to support very unfortunate (and deprecated) curve types, specifically
27* those with a cofactor, or with unreasonable sizes (above 521 bits), which
28* cannot be accomodated by the new faster EC library in math/pcurves. For
29* normal curves EC_AffinePoint will typically be 2 or 3 times faster.
30*
31* This type will be completely removed in Botan4
32*/
34 public:
38
40 using enum EC_Point_Format;
41
42 enum { WORKSPACE_SIZE = 8 };
43
44 /**
45 * Construct an uninitialized EC_Point
46 */
47 EC_Point() = default;
48
49 /**
50 * Construct the zero point
51 * @param curve The base curve
52 */
53 BOTAN_DEPRECATED("Deprecated no replacement") explicit EC_Point(const CurveGFp& curve);
54
55 /**
56 * Copy constructor
57 */
58 EC_Point(const EC_Point&) = default;
59
60 /**
61 * Move Constructor
62 */
63 EC_Point(EC_Point&& other) { this->swap(other); }
64
65 /**
66 * Standard Assignment
67 */
68 EC_Point& operator=(const EC_Point&) = default;
69
70 /**
71 * Move Assignment
72 */
74 if(this != &other) {
75 this->swap(other);
76 }
77 return (*this);
78 }
79
80 /**
81 * Point multiplication operator
82 *
83 * Simple unblinded Montgomery ladder
84 *
85 * Warning: prefer the functions on EC_Group such as
86 * blinded_var_point_multiply
87 *
88 * @param scalar the scalar value
89 * @return *this multiplied by the scalar value
90 */
91 EC_Point mul(const BigInt& scalar) const;
92
93 /**
94 * Construct a point from its affine coordinates
95 * @param curve the base curve
96 * @param x affine x coordinate
97 * @param y affine y coordinate
98 */
99 BOTAN_DEPRECATED("Use EC_AffinePoint::from_bigint_xy") EC_Point(const CurveGFp& curve, BigInt x, BigInt y);
100
101 /**
102 * EC2OSP - elliptic curve to octet string primitive
103 * @param format which format to encode using
104 */
105 std::vector<uint8_t> encode(EC_Point_Format format) const;
106
107 /**
108 * += Operator
109 * @param rhs the EC_Point to add to the local value
110 * @result resulting EC_Point
111 */
112 EC_Point& operator+=(const EC_Point& rhs);
113
114 /**
115 * -= Operator
116 * @param rhs the EC_Point to subtract from the local value
117 * @result resulting EC_Point
118 */
119 EC_Point& operator-=(const EC_Point& rhs);
120
121 /**
122 * *= Operator
123 * @param scalar the EC_Point to multiply with *this
124 * @result resulting EC_Point
125 */
126 EC_Point& operator*=(const BigInt& scalar);
127
128 /**
129 * Negate this point
130 * @return *this
131 */
132 EC_Point& negate() {
133 if(!is_zero()) {
134 m_y = m_curve.get_p() - m_y;
135 }
136 return *this;
137 }
138
139 /**
140 * Force this point to affine coordinates
141 *
142 * Convert the point to its equivalent affine coordinates. Throws if this
143 * is the point at infinity.
144 */
145 void force_affine();
146
147 /**
148 * Force all points on the list to affine coordinates
149 *
150 * Force several points to be affine at once. Uses Montgomery's trick to
151 * reduce number of inversions required, so this is much faster than
152 * calling ``force_affine`` on each point in sequence.
153 */
154 static void force_all_affine(std::span<EC_Point> points, secure_vector<word>& ws);
155
156 bool is_affine() const;
157
158 /**
159 * Is this the point at infinity?
160 * @result true, if this point is at infinity, false otherwise.
161 */
162 bool is_zero() const { return m_z.is_zero(); }
163
164 /**
165 * Checks whether the point is to be found on the underlying
166 * curve; used to prevent fault attacks.
167 * @return if the point is on the curve
168 */
169 bool on_the_curve() const;
170
171 /**
172 * Return the fixed length big endian encoding of x coordinate
173 */
174 secure_vector<uint8_t> x_bytes() const;
175
176 /**
177 * Return the fixed length big endian encoding of y coordinate
178 */
179 secure_vector<uint8_t> y_bytes() const;
180
181 /**
182 * Return the fixed length concatenation of the x and y coordinates
183 */
184 secure_vector<uint8_t> xy_bytes() const;
185
186 /**
187 * get affine x coordinate
188 * @result affine x coordinate
189 */
190 BigInt get_affine_x() const;
191
192 /**
193 * get affine y coordinate
194 * @result affine y coordinate
195 */
196 BigInt get_affine_y() const;
197
198 /**
199 * Return the zero (aka infinite) point associated with this curve
200 */
201 EC_Point zero() const;
202
203 /**
204 * Randomize the point representation
205 * The actual value (get_affine_x, get_affine_y) does not change
206 */
207 void randomize_repr(RandomNumberGenerator& rng);
208
209 /**
210 * Equality operator
211 */
212 bool operator==(const EC_Point& other) const;
213
214 bool operator!=(const EC_Point& other) const = default;
215
216 /**
217 * swaps the states of *this and other
218 * @param other the object to swap values with
219 */
220 void swap(EC_Point& other) noexcept;
221
222 /**
223 * For internal use only
224 */
225 bool _is_x_eq_to_v_mod_order(const BigInt& v) const;
226
227#if defined(BOTAN_DISABLE_DEPRECATED_FEATURES)
228
229 private:
230#endif
231
232 /**
233 * Return the internal x coordinate
234 *
235 * Note this may be in Montgomery form
236 */
237 BOTAN_DEPRECATED("Use affine coordinates only") const BigInt& get_x() const { return m_x; }
238
239 /**
240 * Return the internal y coordinate
241 *
242 * Note this may be in Montgomery form
243 */
244 BOTAN_DEPRECATED("Use affine coordinates only") const BigInt& get_y() const { return m_y; }
245
246 /**
247 * Return the internal z coordinate
248 *
249 * Note this may be in Montgomery form
250 */
251 BOTAN_DEPRECATED("Use affine coordinates only") const BigInt& get_z() const { return m_z; }
252
253 BOTAN_DEPRECATED("Deprecated no replacement")
254
255 void swap_coords(BigInt& new_x, BigInt& new_y, BigInt& new_z) {
256 m_x.swap(new_x);
257 m_y.swap(new_y);
258 m_z.swap(new_z);
259 }
260
261 friend void swap(EC_Point& x, EC_Point& y) { x.swap(y); }
262
263 /**
264 * Randomize the point representation
265 * The actual value (get_affine_x, get_affine_y) does not change
266 */
267 void randomize_repr(RandomNumberGenerator& rng, secure_vector<word>& ws);
268
269 /**
270 * Point addition
271 * @param other the point to add to *this
272 * @param workspace temp space, at least WORKSPACE_SIZE elements
273 */
274 void add(const EC_Point& other, std::vector<BigInt>& workspace) {
275 BOTAN_ARG_CHECK(m_curve == other.m_curve, "cannot add points on different curves");
276
277 const size_t p_words = m_curve.get_p_words();
278
279 add(other.m_x._data(),
280 std::min(p_words, other.m_x.size()),
281 other.m_y._data(),
282 std::min(p_words, other.m_y.size()),
283 other.m_z._data(),
284 std::min(p_words, other.m_z.size()),
285 workspace);
286 }
287
288 /**
289 * Point addition. Array version.
290 *
291 * @param x_words the words of the x coordinate of the other point
292 * @param x_size size of x_words
293 * @param y_words the words of the y coordinate of the other point
294 * @param y_size size of y_words
295 * @param z_words the words of the z coordinate of the other point
296 * @param z_size size of z_words
297 * @param workspace temp space, at least WORKSPACE_SIZE elements
298 */
299 void add(const word x_words[],
300 size_t x_size,
301 const word y_words[],
302 size_t y_size,
303 const word z_words[],
304 size_t z_size,
305 std::vector<BigInt>& workspace);
306
307 /**
308 * Point addition - mixed J+A
309 *
310 * @warning This function assumes that @p other is affine, if this is not
311 * correct the result will be invalid.
312 *
313 * @param other affine point to add - assumed to be affine!
314 * @param workspace temp space, at least WORKSPACE_SIZE elements
315 */
316 void add_affine(const EC_Point& other, std::vector<BigInt>& workspace) {
317 BOTAN_ASSERT_NOMSG(m_curve == other.m_curve);
319
320 const size_t p_words = m_curve.get_p_words();
321 add_affine(other.m_x._data(),
322 std::min(p_words, other.m_x.size()),
323 other.m_y._data(),
324 std::min(p_words, other.m_y.size()),
325 workspace);
326 }
327
328 /**
329 * Point addition - mixed J+A. Array version.
330 *
331 * @param x_words the words of the x coordinate of the other point
332 * @param x_size size of x_words
333 * @param y_words the words of the y coordinate of the other point
334 * @param y_size size of y_words
335 * @param workspace temp space, at least WORKSPACE_SIZE elements
336 */
337 void add_affine(
338 const word x_words[], size_t x_size, const word y_words[], size_t y_size, std::vector<BigInt>& workspace);
339
340 /**
341 * Point doubling
342 * @param workspace temp space, at least WORKSPACE_SIZE elements
343 */
344 void mult2(std::vector<BigInt>& workspace);
345
346 /**
347 * Repeated point doubling
348 * @param i number of doublings to perform
349 * @param workspace temp space, at least WORKSPACE_SIZE elements
350 */
351 void mult2i(size_t i, std::vector<BigInt>& workspace);
352
353 /**
354 * Point addition
355 * @param other the point to add to *this
356 * @param workspace temp space, at least WORKSPACE_SIZE elements
357 * @return other plus *this
358 */
359 EC_Point plus(const EC_Point& other, std::vector<BigInt>& workspace) const {
360 EC_Point x = (*this);
361 x.add(other, workspace);
362 return x;
363 }
364
365 /**
366 * Point doubling
367 * @param workspace temp space, at least WORKSPACE_SIZE elements
368 * @return *this doubled
369 */
370 EC_Point double_of(std::vector<BigInt>& workspace) const {
371 EC_Point x = (*this);
372 x.mult2(workspace);
373 return x;
374 }
375
376 /**
377 * Return base curve of this point
378 * @result the curve over GF(p) of this point
379 *
380 * You should not need to use this
381 */
382 BOTAN_DEPRECATED("Deprecated no replacement") const CurveGFp& get_curve() const { return m_curve; }
383
384 private:
385 CurveGFp m_curve;
386 BigInt m_x, m_y, m_z;
387};
388
389/**
390* ECC point multiexponentiation - not constant time!
391* @param p1 a point
392* @param z1 a scalar
393* @param p2 a point
394* @param z2 a scalar
395* @result (p1 * z1 + p2 * z2)
396*/
397BOTAN_DEPRECATED("Use EC_AffinePoint::mul_px_qy")
398EC_Point BOTAN_PUBLIC_API(2, 0)
399 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_AffinePoint::deserialize")
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*
434* This is an internal function which was accidentally made public.
435* Do not use it; it will be removed in Botan4.
436*
437* @param data the encoded point
438* @param data_len length of data in bytes
439* @param curve_p the curve equation prime
440* @param curve_a the curve equation a parameter
441* @param curve_b the curve equation b parameter
442*/
443BOTAN_DEPRECATED("Use EC_AffinePoint::deserialize")
444std::pair<BigInt, BigInt> BOTAN_UNSTABLE_API
445 OS2ECP(const uint8_t data[], size_t data_len, const BigInt& curve_p, const BigInt& curve_a, const BigInt& curve_b);
446
447BOTAN_DEPRECATED("Use EC_AffinePoint::deserialize")
448EC_Point BOTAN_UNSTABLE_API OS2ECP(std::span<const uint8_t> data, const CurveGFp& curve);
449
450// The name used for this type in older versions
452
453} // namespace Botan
454
455#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:19
#define BOTAN_UNSTABLE_API
Definition api.h:32
#define BOTAN_DEPRECATED(msg)
Definition api.h:59
#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
size_t size() const
Definition bigint.h:610
const word * _data() const
Definition bigint.h:936
EC_Point & negate()
Definition ec_point.h:132
void swap(EC_Point &other) noexcept
Definition ec_point.cpp:741
bool operator!=(const EC_Point &other) const =default
EC_Point & operator=(EC_Point &&other)
Definition ec_point.h:73
EC_Point plus(const EC_Point &other, std::vector< BigInt > &workspace) const
Definition ec_point.h:359
void add(const EC_Point &other, std::vector< BigInt > &workspace)
Definition ec_point.h:274
void add_affine(const EC_Point &other, std::vector< BigInt > &workspace)
Definition ec_point.h:316
void mult2(std::vector< BigInt > &workspace)
Definition ec_point.cpp:351
EC_Point double_of(std::vector< BigInt > &workspace) const
Definition ec_point.h:370
bool is_zero() const
Definition ec_point.h:162
bool is_affine() const
Definition ec_point.cpp:562
EC_Point mul(const BigInt &scalar) const
Definition ec_point.cpp:460
EC_Point & operator=(const EC_Point &)=default
friend void swap(EC_Point &x, EC_Point &y)
Definition ec_point.h:261
EC_Point()=default
EC_Point_Format Compression_Type
Definition ec_point.h:39
int(* final)(unsigned char *, CTX *)
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:34
BigInt operator-(const BigInt &x, const BigInt &y)
Definition bigint.h:1094
bool operator==(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition alg_id.cpp:54
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
EC_Point OS2ECP(std::span< const uint8_t > data, const CurveGFp &curve)
Definition ec_point.cpp:815