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