Botan 3.3.0
Crypto and TLS for C&
ec_group.h
Go to the documentation of this file.
1/*
2* ECC Domain Parameters
3*
4* (C) 2007 Falko Strenzke, FlexSecure GmbH
5* 2008-2010 Jack Lloyd
6*
7* Botan is released under the Simplified BSD License (see license.txt)
8*/
9
10#ifndef BOTAN_ECC_DOMAIN_PARAMETERS_H_
11#define BOTAN_ECC_DOMAIN_PARAMETERS_H_
12
13#include <botan/asn1_obj.h>
14#include <botan/ec_point.h>
15#include <memory>
16#include <set>
17#include <span>
18
19namespace Botan {
20
21/**
22* This class represents elliptic curce domain parameters
23*/
33
34enum class EC_Group_Source {
35 Builtin,
37};
38
39class EC_Group_Data;
40class EC_Group_Data_Map;
41
42/**
43* Class representing an elliptic curve
44*
45* The internal representation is stored in a shared_ptr, so copying an
46* EC_Group is inexpensive.
47*/
49 public:
50 /**
51 * Construct Domain paramers from specified parameters
52 * @param p the elliptic curve p
53 * @param a the elliptic curve a param
54 * @param b the elliptic curve b param
55 * @param base_x the x coordinate of the base point
56 * @param base_y the y coordinate of the base point
57 * @param order the order of the base point
58 * @param cofactor the cofactor
59 * @param oid an optional OID used to identify this curve
60 */
61 EC_Group(const BigInt& p,
62 const BigInt& a,
63 const BigInt& b,
64 const BigInt& base_x,
65 const BigInt& base_y,
66 const BigInt& order,
67 const BigInt& cofactor,
68 const OID& oid = OID());
69
70 /**
71 * Decode a BER encoded ECC domain parameter set
72 * @param ber the bytes of the BER encoding
73 * @param ber_len the length of ber
74 */
75 explicit EC_Group(const uint8_t ber[], size_t ber_len);
76
77 template <typename Alloc>
78 EC_Group(const std::vector<uint8_t, Alloc>& ber) : EC_Group(ber.data(), ber.size()) {}
79
80 /**
81 * Create an EC domain by OID (or throw if unknown)
82 * @param oid the OID of the EC domain to create
83 */
84 explicit EC_Group(const OID& oid);
85
86 /**
87 * Create an EC domain from PEM encoding (as from PEM_encode), or
88 * from an OID name (eg "secp256r1", or "1.2.840.10045.3.1.7")
89 * @param pem_or_oid PEM-encoded data, or an OID
90
91 * @warning Support for PEM in this function is deprecated. Use
92 * EC_Group_from_PEM
93 */
94 explicit EC_Group(std::string_view pem_or_oid);
95
96 static EC_Group EC_Group_from_PEM(std::string_view pem);
97
98 /**
99 * Create an uninitialized EC_Group
100 */
102
104
105 EC_Group(const EC_Group&) = default;
106 EC_Group(EC_Group&&) = default;
107
108 EC_Group& operator=(const EC_Group&) = default;
110
111 /**
112 * Create the DER encoding of this domain
113 * @param form of encoding to use
114 * @returns bytes encododed as DER
115 */
116 std::vector<uint8_t> DER_encode(EC_Group_Encoding form) const;
117
118 /**
119 * Return the PEM encoding (always in explicit form)
120 * @return string containing PEM data
121 */
122 std::string PEM_encode() const;
123
124 /**
125 * Return if a == -3 mod p
126 */
127 bool a_is_minus_3() const;
128
129 /**
130 * Return if a == 0 mod p
131 */
132 bool a_is_zero() const;
133
134 /**
135 * Return the size of p in bits (same as get_p().bits())
136 */
137 size_t get_p_bits() const;
138
139 /**
140 * Return the size of p in bits (same as get_p().bytes())
141 */
142 size_t get_p_bytes() const;
143
144 /**
145 * Return the size of group order in bits (same as get_order().bits())
146 */
147 size_t get_order_bits() const;
148
149 /**
150 * Return the size of p in bytes (same as get_order().bytes())
151 */
152 size_t get_order_bytes() const;
153
154 /**
155 * Return the prime modulus of the field
156 */
157 const BigInt& get_p() const;
158
159 /**
160 * Return the a parameter of the elliptic curve equation
161 */
162 const BigInt& get_a() const;
163
164 /**
165 * Return the b parameter of the elliptic curve equation
166 */
167 const BigInt& get_b() const;
168
169 /**
170 * Return group base point
171 * @result base point
172 */
173 const EC_Point& get_base_point() const;
174
175 /**
176 * Return the x coordinate of the base point
177 */
178 const BigInt& get_g_x() const;
179
180 /**
181 * Return the y coordinate of the base point
182 */
183 const BigInt& get_g_y() const;
184
185 /**
186 * Return the order of the base point
187 * @result order of the base point
188 */
189 const BigInt& get_order() const;
190
191 /**
192 * Return the cofactor
193 * @result the cofactor
194 */
195 const BigInt& get_cofactor() const;
196
197 /*
198 * Reduce x modulo the order
199 */
200 BigInt mod_order(const BigInt& x) const;
201
202 /*
203 * Return inverse of x modulo the order
204 */
205 BigInt inverse_mod_order(const BigInt& x) const;
206
207 /*
208 * Reduce (x*x) modulo the order
209 */
210 BigInt square_mod_order(const BigInt& x) const;
211
212 /*
213 * Reduce (x*y) modulo the order
214 */
215 BigInt multiply_mod_order(const BigInt& x, const BigInt& y) const;
216
217 /*
218 * Reduce (x*y*z) modulo the order
219 */
220 BigInt multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const;
221
222 /*
223 * Return x^3 modulo the order
224 */
225 inline BigInt cube_mod_order(const BigInt& x) const { return multiply_mod_order(x, square_mod_order(x)); }
226
227 /**
228 * Check if y is a plausible point on the curve
229 *
230 * In particular, checks that it is a point on the curve, not infinity,
231 * and that it has order matching the group.
232 */
233 bool verify_public_element(const EC_Point& y) const;
234
235 /**
236 * Return the OID of these domain parameters
237 * @result the OID
238 */
239 const OID& get_curve_oid() const;
240
241 /**
242 * Return a point on this curve with the affine values x, y
243 */
244 EC_Point point(const BigInt& x, const BigInt& y) const;
245
246 /**
247 * Multi exponentiate. Not constant time.
248 * @return base_point*x + pt*y
249 */
250 EC_Point point_multiply(const BigInt& x, const EC_Point& pt, const BigInt& y) const;
251
252 /**
253 * Blinded point multiplication, attempts resistance to side channels
254 * @param k the scalar
255 * @param rng a random number generator
256 * @param ws a temp workspace
257 * @return base_point*k
258 */
259 EC_Point blinded_base_point_multiply(const BigInt& k, RandomNumberGenerator& rng, std::vector<BigInt>& ws) const;
260
261 /**
262 * Blinded point multiplication, attempts resistance to side channels
263 * Returns just the x coordinate of the point
264 *
265 * @param k the scalar
266 * @param rng a random number generator
267 * @param ws a temp workspace
268 * @return x coordinate of base_point*k
269 */
270 BigInt blinded_base_point_multiply_x(const BigInt& k, RandomNumberGenerator& rng, std::vector<BigInt>& ws) const;
271
272 /**
273 * Blinded point multiplication, attempts resistance to side channels
274 * @param point input point
275 * @param k the scalar
276 * @param rng a random number generator
277 * @param ws a temp workspace
278 * @return point*k
279 */
280 EC_Point blinded_var_point_multiply(const EC_Point& point,
281 const BigInt& k,
283 std::vector<BigInt>& ws) const;
284
285 /**
286 * Return a random scalar ie an integer in [1,order)
287 */
288 BigInt random_scalar(RandomNumberGenerator& rng) const;
289
290 /**
291 * Hash onto the curve.
292 * For some curve types no mapping is currently available, in this
293 * case this function will throw an exception.
294 *
295 * @param hash_fn the hash function to use (typically "SHA-256" or "SHA-512")
296 * @param input the input to hash
297 * @param input_len length of input in bytes
298 * @param domain_sep a domain seperator
299 * @param domain_sep_len length of domain_sep in bytes
300 * @param random_oracle if the mapped point must be uniform (use
301 "true" here unless you know what you are doing)
302 */
303 EC_Point hash_to_curve(std::string_view hash_fn,
304 const uint8_t input[],
305 size_t input_len,
306 const uint8_t domain_sep[],
307 size_t domain_sep_len,
308 bool random_oracle = true) const;
309
310 /**
311 * Hash onto the curve.
312 * For some curve types no mapping is currently available, in this
313 * case this function will throw an exception.
314 *
315 * @param hash_fn the hash function to use (typically "SHA-256" or "SHA-512")
316 * @param input the input to hash
317 * @param input_len length of input in bytes
318 * @param domain_sep a domain seperator
319 * @param random_oracle if the mapped point must be uniform (use
320 "true" here unless you know what you are doing)
321 */
322 EC_Point hash_to_curve(std::string_view hash_fn,
323 const uint8_t input[],
324 size_t input_len,
325 std::string_view domain_sep,
326 bool random_oracle = true) const;
327
328 /**
329 * Return the zero (or infinite) point on this curve
330 */
331 EC_Point zero_point() const;
332
333 size_t point_size(EC_Point_Format format) const;
334
335 EC_Point OS2ECP(const uint8_t bits[], size_t len) const;
336
337 EC_Point OS2ECP(std::span<const uint8_t> encoded_point) const {
338 return this->OS2ECP(encoded_point.data(), encoded_point.size());
339 }
340
341 bool initialized() const { return (m_data != nullptr); }
342
343 /**
344 * Verify EC_Group domain
345 * @returns true if group is valid. false otherwise
346 */
347 bool verify_group(RandomNumberGenerator& rng, bool strong = false) const;
348
349 bool operator==(const EC_Group& other) const;
350
351 EC_Group_Source source() const;
352
353 /**
354 * Return true if this EC_Group was derived from an explicit encoding
355 *
356 * Explicit encoding of groups is deprecated; when support for explicit curves
357 * is removed in a future major release, this function will also be removed.
358 */
359 bool used_explicit_encoding() const { return m_explicit_encoding; }
360
361 /**
362 * Return a set of known named EC groups
363 */
364 static const std::set<std::string>& known_named_groups();
365
366 /*
367 * For internal use only
368 */
369 static std::shared_ptr<EC_Group_Data> EC_group_info(const OID& oid);
370
371 /*
372 * For internal use only
373 */
374 static size_t clear_registered_curve_data();
375
376 /*
377 * For internal use only
378 */
379 static OID EC_group_identity_from_order(const BigInt& order);
380
381 private:
382 static EC_Group_Data_Map& ec_group_data();
383
384 static std::pair<std::shared_ptr<EC_Group_Data>, bool> BER_decode_EC_group(const uint8_t bits[],
385 size_t len,
386 EC_Group_Source source);
387
388 static std::shared_ptr<EC_Group_Data> load_EC_group_info(const char* p,
389 const char* a,
390 const char* b,
391 const char* g_x,
392 const char* g_y,
393 const char* order,
394 const OID& oid);
395
396 // Member data
397 const EC_Group_Data& data() const;
398 std::shared_ptr<EC_Group_Data> m_data;
399 bool m_explicit_encoding = false;
400};
401
402inline bool operator!=(const EC_Group& lhs, const EC_Group& rhs) {
403 return !(lhs == rhs);
404}
405
406} // namespace Botan
407
408#endif
bool initialized() const
Definition ec_group.h:341
EC_Group(const EC_Group &)=default
BigInt cube_mod_order(const BigInt &x) const
Definition ec_group.h:225
EC_Group & operator=(EC_Group &&)=default
bool used_explicit_encoding() const
Definition ec_group.h:359
EC_Point OS2ECP(std::span< const uint8_t > encoded_point) const
Definition ec_group.h:337
EC_Group(EC_Group &&)=default
EC_Group(const std::vector< uint8_t, Alloc > &ber)
Definition ec_group.h:78
EC_Group & operator=(const EC_Group &)=default
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition compiler.h:31
EC_Group_Source
Definition ec_group.h:34
bool operator!=(const AlgorithmIdentifier &a1, const AlgorithmIdentifier &a2)
Definition alg_id.cpp:69
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:627
EC_Group_Encoding
Definition ec_group.h:24