Botan 3.7.1
Crypto and TLS for C&
ec_apoint.h
Go to the documentation of this file.
1/*
2* (C) 2024 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#ifndef BOTAN_EC_APOINT_H_
8#define BOTAN_EC_APOINT_H_
9
10#include <botan/concepts.h>
11#include <botan/ec_point_format.h>
12#include <botan/secmem.h>
13#include <botan/types.h>
14#include <optional>
15#include <span>
16#include <string_view>
17#include <vector>
18
19namespace Botan {
20
21class BigInt;
22class RandomNumberGenerator;
23class EC_Group;
24class EC_Scalar;
25
26#if defined(BOTAN_HAS_LEGACY_EC_POINT)
27class EC_Point;
28#endif
29
30class EC_Group_Data;
31class EC_AffinePoint_Data;
32
33/// Elliptic Curve Point in Affine Representation
34///
36 public:
37 /// Point deserialization. Throws if wrong length or not a valid point
38 ///
39 /// This accepts SEC1 compressed or uncompressed formats
40 EC_AffinePoint(const EC_Group& group, std::span<const uint8_t> bytes);
41
42 /// Point deserialization. Returns nullopt if wrong length or not a valid point
43 ///
44 /// This accepts SEC1 compressed or uncompressed formats
45 static std::optional<EC_AffinePoint> deserialize(const EC_Group& group, std::span<const uint8_t> bytes);
46
47 /// Create a point from a pair (x,y) of integers
48 ///
49 /// The integers must be within the field - in the range [0,p) and must
50 /// satisfy the curve equation
51 static std::optional<EC_AffinePoint> from_bigint_xy(const EC_Group& group, const BigInt& x, const BigInt& y);
52
53 /// Multiply by the group generator returning a complete point
54 ///
55 /// Workspace argument is transitional
56 static EC_AffinePoint g_mul(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws);
57
58 /// Return the identity element
59 static EC_AffinePoint identity(const EC_Group& group);
60
61 /// Return the standard group generator
62 static EC_AffinePoint generator(const EC_Group& group);
63
64 /// Hash to curve (RFC 9380), random oracle variant
65 ///
66 /// Only supported for specific groups
67 static EC_AffinePoint hash_to_curve_ro(const EC_Group& group,
68 std::string_view hash_fn,
69 std::span<const uint8_t> input,
70 std::span<const uint8_t> domain_sep);
71
72 /// Hash to curve (RFC 9380), non uniform variant
73 ///
74 /// Only supported for specific groups
75 static EC_AffinePoint hash_to_curve_nu(const EC_Group& group,
76 std::string_view hash_fn,
77 std::span<const uint8_t> input,
78 std::span<const uint8_t> domain_sep);
79
80 /// Multiply a point by a scalar returning a complete point
81 ///
82 /// Workspace argument is transitional
83 EC_AffinePoint mul(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws) const;
84
85 /// Multiply a point by a scalar, returning the byte encoding of the x coordinate only
86 ///
87 /// Workspace argument is transitional
88 secure_vector<uint8_t> mul_x_only(const EC_Scalar& scalar,
90 std::vector<BigInt>& ws) const;
91
92 /// Compute 2-ary multiscalar multiplication - p*x + q*y
93 ///
94 /// This operation runs in constant time with respect to p, x, q, and y
95 ///
96 /// @returns p*x+q*y, or nullopt if the result was the point at infinity
97 static std::optional<EC_AffinePoint> mul_px_qy(const EC_AffinePoint& p,
98 const EC_Scalar& x,
99 const EC_AffinePoint& q,
100 const EC_Scalar& y,
102
103 /// Point addition
104 ///
105 /// Note that this is quite slow since it converts the resulting
106 /// projective point immediately to affine coordinates, which requires a
107 /// field inversion. This can be sufficient when implementing protocols
108 /// that just need to perform a few additions.
109 ///
110 /// In the future a cooresponding EC_ProjectivePoint type may be added
111 /// which would avoid the expensive affine conversions
112 EC_AffinePoint add(const EC_AffinePoint& q) const;
113
114 /// Point negation
115 EC_AffinePoint negate() const;
116
117 /// Return the number of bytes of a field element
118 ///
119 /// A point consists of two field elements, plus possibly a header
120 size_t field_element_bytes() const;
121
122 /// Return true if this point is the identity element
123 bool is_identity() const;
124
125 /// Write the fixed length encoding of affine x coordinate
126 ///
127 /// The output span must be exactly field_element_bytes long
128 ///
129 /// This function will fail if this point is the identity element
130 void serialize_x_to(std::span<uint8_t> bytes) const;
131
132 /// Write the fixed length encoding of affine y coordinate
133 ///
134 /// The output span must be exactly field_element_bytes long
135 ///
136 /// This function will fail if this point is the identity element
137 void serialize_y_to(std::span<uint8_t> bytes) const;
138
139 /// Write the fixed length encoding of affine x and y coordinates
140 ///
141 /// The output span must be exactly 2*field_element_bytes long
142 ///
143 /// This function will fail if this point is the identity element
144 void serialize_xy_to(std::span<uint8_t> bytes) const;
145
146 /// Write the fixed length SEC1 compressed encoding
147 ///
148 /// The output span must be exactly 1 + field_element_bytes long
149 ///
150 /// This function will fail if this point is the identity element
151 void serialize_compressed_to(std::span<uint8_t> bytes) const;
152
153 /// Return the fixed length encoding of SEC1 uncompressed encoding
154 ///
155 /// The output span must be exactly 1 + 2*field_element_bytes long
156 ///
157 /// This function will fail if this point is the identity element
158 void serialize_uncompressed_to(std::span<uint8_t> bytes) const;
159
160 /// Return the bytes of the affine x coordinate in a container
161 ///
162 /// This function will fail if this point is the identity element
163 template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
164 T x_bytes() const {
165 T bytes(this->field_element_bytes());
166 this->serialize_x_to(bytes);
167 return bytes;
168 }
169
170 /// Return the bytes of the affine y coordinate in a container
171 ///
172 /// This function will fail if this point is the identity element
173 template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
174 T y_bytes() const {
175 T bytes(this->field_element_bytes());
176 this->serialize_y_to(bytes);
177 return bytes;
178 }
179
180 /// Return the bytes of the affine x and y coordinates in a container
181 ///
182 /// This function will fail if this point is the identity element
183 template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
184 T xy_bytes() const {
185 T bytes(2 * this->field_element_bytes());
186 this->serialize_xy_to(bytes);
187 return bytes;
188 }
189
190 /// Return the bytes of the affine x and y coordinates in a container
191 ///
192 /// This function will fail if this point is the identity element
193 template <concepts::resizable_byte_buffer T = std::vector<uint8_t>>
195 T bytes(1 + 2 * this->field_element_bytes());
196 this->serialize_uncompressed_to(bytes);
197 return bytes;
198 }
199
200 /// Return the bytes of the affine x and y coordinates in a container
201 ///
202 /// This function will fail if this point is the identity element
203 template <concepts::resizable_byte_buffer T = std::vector<uint8_t>>
205 T bytes(1 + this->field_element_bytes());
206 this->serialize_compressed_to(bytes);
207 return bytes;
208 }
209
210 bool operator==(const EC_AffinePoint& other) const;
211
212 bool operator!=(const EC_AffinePoint& other) const { return !(*this == other); }
213
214 /// Return an encoding depending on the requested format
215 std::vector<uint8_t> serialize(EC_Point_Format format) const;
216
217 EC_AffinePoint(const EC_AffinePoint& other);
218 EC_AffinePoint(EC_AffinePoint&& other) noexcept;
219
220 EC_AffinePoint& operator=(const EC_AffinePoint& other);
221 EC_AffinePoint& operator=(EC_AffinePoint&& other) noexcept;
222
223#if defined(BOTAN_HAS_LEGACY_EC_POINT)
224 /**
225 * Deprecated conversion
226 */
227 EC_AffinePoint(const EC_Group& group, const EC_Point& pt);
228
229 /**
230 * Deprecated conversion
231 */
232 EC_Point to_legacy_point() const;
233#endif
234
236
237 const EC_AffinePoint_Data& _inner() const { return inner(); }
238
239 static EC_AffinePoint _from_inner(std::unique_ptr<EC_AffinePoint_Data> inner);
240
241 const std::shared_ptr<const EC_Group_Data>& _group() const;
242
243 private:
244 friend class EC_Mul2Table;
245
246 EC_AffinePoint(std::unique_ptr<EC_AffinePoint_Data> point);
247
248 const EC_AffinePoint_Data& inner() const { return *m_point; }
249
250 std::unique_ptr<EC_AffinePoint_Data> m_point;
251};
252
253} // namespace Botan
254
255#endif
#define BOTAN_UNSTABLE_API
Definition api.h:32
bool operator!=(const EC_AffinePoint &other) const
Definition ec_apoint.h:212
T serialize_uncompressed() const
Definition ec_apoint.h:194
T serialize_compressed() const
Definition ec_apoint.h:204
const EC_AffinePoint_Data & _inner() const
Definition ec_apoint.h:237
int(* final)(unsigned char *, CTX *)
FE_25519 T
Definition ge.cpp:34
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