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