Botan 3.5.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 elliptic curve from the specified parameters
52 *
53 * @param p the elliptic curve p
54 * @param a the elliptic curve a param
55 * @param b the elliptic curve b param
56 * @param base_x the x coordinate of the base point
57 * @param base_y the y coordinate of the base point
58 * @param order the order of the base point
59 * @param cofactor the cofactor
60 * @param oid an optional OID used to identify this curve
61 *
62 * @warning This constructor is deprecated and will be removed in Botan 4
63 *
64 * @warning support for cofactors > 1 is deprecated and will be removed
65 *
66 * @warning support for prime fields > 521 bits is deprecated and
67 * will be removed.
68 *
69 * @warning Support for explicitly encoded curve parameters is deprecated.
70 * An OID must be assigned.
71 */
72 BOTAN_DEPRECATED("Use alternate constructor")
73 EC_Group(const BigInt& p,
74 const BigInt& a,
75 const BigInt& b,
76 const BigInt& base_x,
77 const BigInt& base_y,
78 const BigInt& order,
79 const BigInt& cofactor,
80 const OID& oid = OID());
81
82 /**
83 * Construct elliptic curve from the specified parameters
84 *
85 * Unlike the deprecated constructor, this constructor imposes
86 * additional restrictions on the parameters, namely:
87 *
88 * - The prime must be at least 128 bits and at most 512 bits, and
89 * a multiple of 32 bits.
90 * - As an extension of the above restriction, the prime can
91 * also be exactly the 521-bit Mersenne prime (2**521-1)
92 * - The prime must be congruent to 3 modulo 4
93 * - The group order must have the same bit length as the prime
94 * (It is allowed for the order to be larger than p, but they
95 * must have the same bit length)
96 * - An object identifier must be provided
97 * - There must be no cofactor
98 *
99 * @warning use only elliptic curve parameters that you trust
100 *
101 * @param oid an object identifier used to identify this curve
102 * @param p the elliptic curve prime (at most 521 bits)
103 * @param a the elliptic curve a param
104 * @param b the elliptic curve b param
105 * @param base_x the x coordinate of the group generator
106 * @param base_y the y coordinate of the group generator
107 * @param order the order of the group
108 */
109 EC_Group(const OID& oid,
110 const BigInt& p,
111 const BigInt& a,
112 const BigInt& b,
113 const BigInt& base_x,
114 const BigInt& base_y,
115 const BigInt& order);
116
117 /**
118 * Decode a BER encoded ECC domain parameter set
119 * @param ber the bytes of the BER encoding
120 */
121 explicit EC_Group(std::span<const uint8_t> ber);
122
123 BOTAN_DEPRECATED("Use EC_Group(std::span)")
124 EC_Group(const uint8_t ber[], size_t ber_len) : EC_Group(std::span{ber, ber_len}) {}
125
126 /**
127 * Create an EC domain by OID (or throw if unknown)
128 * @param oid the OID of the EC domain to create
129 */
130 BOTAN_DEPRECATED("Use EC_Group::from_OID") explicit EC_Group(const OID& oid) { *this = EC_Group::from_OID(oid); }
131
132 /**
133 * Create an EC domain from PEM encoding (as from PEM_encode), or
134 * from an OID name (eg "secp256r1", or "1.2.840.10045.3.1.7")
135 * @param pem_or_oid PEM-encoded data, or an OID
136 *
137 * @warning Support for PEM in this function is deprecated. Use
138 * EC_Group::from_PEM or EC_Group::from_OID or EC_Group::from_name
139 */
140 BOTAN_DEPRECATED("Use EC_Group::from_{name,OID,PEM}") explicit EC_Group(std::string_view pem_or_oid);
141
142 /**
143 * Initialize an EC group from the PEM/ASN.1 encoding
144 */
145 static EC_Group from_PEM(std::string_view pem);
146
147 /**
148 * Initialize an EC group from a group named by an object identifier
149 */
150 static EC_Group from_OID(const OID& oid);
151
152 /**
153 * Initialize an EC group from a group common name (eg "secp256r1")
154 */
155 static EC_Group from_name(std::string_view name);
156
157 BOTAN_DEPRECATED("Use EC_Group::from_PEM") static EC_Group EC_Group_from_PEM(std::string_view pem) {
158 return EC_Group::from_PEM(pem);
159 }
160
161 /**
162 * Create an uninitialized EC_Group
163 */
165
167
169 EC_Group(EC_Group&&) = default;
170
173
174 /**
175 * Create the DER encoding of this domain
176 * @param form of encoding to use
177 * @returns bytes encododed as DER
178 */
179 std::vector<uint8_t> DER_encode(EC_Group_Encoding form) const;
180
181 /**
182 * Return the PEM encoding (always in explicit form)
183 * @return string containing PEM data
184 */
185 std::string PEM_encode() const;
186
187 /**
188 * Return the size of p in bits (same as get_p().bits())
189 */
190 size_t get_p_bits() const;
191
192 /**
193 * Return the size of p in bits (same as get_p().bytes())
194 */
195 size_t get_p_bytes() const;
196
197 /**
198 * Return the size of group order in bits (same as get_order().bits())
199 */
200 size_t get_order_bits() const;
201
202 /**
203 * Return the size of the group order in bytes (same as get_order().bytes())
204 */
205 size_t get_order_bytes() const;
206
207 /**
208 * Check if y is a plausible point on the curve
209 *
210 * In particular, checks that it is a point on the curve, not infinity,
211 * and that it has order matching the group.
212 */
213 bool verify_public_element(const EC_Point& y) const;
214
215 /**
216 * Return the OID of these domain parameters
217 * @result the OID
218 */
219 const OID& get_curve_oid() const;
220
221 /**
222 * Return the prime modulus of the field
223 */
224 const BigInt& get_p() const;
225
226 /**
227 * Return the a parameter of the elliptic curve equation
228 */
229 const BigInt& get_a() const;
230
231 /**
232 * Return the b parameter of the elliptic curve equation
233 */
234 const BigInt& get_b() const;
235
236 /**
237 * Return group base point
238 * @result base point
239 */
240 const EC_Point& get_base_point() const;
241
242 /**
243 * Return the x coordinate of the base point
244 */
245 const BigInt& get_g_x() const;
246
247 /**
248 * Return the y coordinate of the base point
249 */
250 const BigInt& get_g_y() const;
251
252 /**
253 * Return the order of the base point
254 * @result order of the base point
255 */
256 const BigInt& get_order() const;
257
258 /**
259 * Return the cofactor
260 * @result the cofactor
261 */
262 const BigInt& get_cofactor() const;
263
264 /**
265 * Multi exponentiate. Not constant time.
266 * @return base_point*x + pt*y
267 */
268 EC_Point point_multiply(const BigInt& x, const EC_Point& pt, const BigInt& y) const;
269
270 /**
271 * Blinded point multiplication, attempts resistance to side channels
272 * @param k the scalar
273 * @param rng a random number generator
274 * @param ws a temp workspace
275 * @return base_point*k
276 */
277 EC_Point blinded_base_point_multiply(const BigInt& k, RandomNumberGenerator& rng, std::vector<BigInt>& ws) const;
278
279 /**
280 * Blinded point multiplication, attempts resistance to side channels
281 * Returns just the x coordinate of the point
282 *
283 * @param k the scalar
284 * @param rng a random number generator
285 * @param ws a temp workspace
286 * @return x coordinate of base_point*k
287 */
288 BigInt blinded_base_point_multiply_x(const BigInt& k, RandomNumberGenerator& rng, std::vector<BigInt>& ws) const;
289
290 /**
291 * Blinded point multiplication, attempts resistance to side channels
292 * @param point input point
293 * @param k the scalar
294 * @param rng a random number generator
295 * @param ws a temp workspace
296 * @return point*k
297 */
298 EC_Point blinded_var_point_multiply(const EC_Point& point,
299 const BigInt& k,
301 std::vector<BigInt>& ws) const;
302
303 /**
304 * Return a random scalar ie an integer in [1,order)
305 */
306 BigInt random_scalar(RandomNumberGenerator& rng) const;
307
308 /**
309 * Hash onto the curve.
310 * For some curve types no mapping is currently available, in this
311 * case this function will throw an exception.
312 *
313 * @param hash_fn the hash function to use (typically "SHA-256" or "SHA-512")
314 * @param input the input to hash
315 * @param input_len length of input in bytes
316 * @param domain_sep a domain seperator
317 * @param domain_sep_len length of domain_sep in bytes
318 * @param random_oracle if the mapped point must be uniform (use
319 "true" here unless you know what you are doing)
320 */
321 EC_Point hash_to_curve(std::string_view hash_fn,
322 const uint8_t input[],
323 size_t input_len,
324 const uint8_t domain_sep[],
325 size_t domain_sep_len,
326 bool random_oracle = true) const;
327
328 /**
329 * Hash onto the curve.
330 * For some curve types no mapping is currently available, in this
331 * case this function will throw an exception.
332 *
333 * @param hash_fn the hash function to use (typically "SHA-256" or "SHA-512")
334 * @param input the input to hash
335 * @param input_len length of input in bytes
336 * @param domain_sep a domain seperator
337 * @param random_oracle if the mapped point must be uniform (use
338 "true" here unless you know what you are doing)
339 */
340 EC_Point hash_to_curve(std::string_view hash_fn,
341 const uint8_t input[],
342 size_t input_len,
343 std::string_view domain_sep,
344 bool random_oracle = true) const;
345
346 /**
347 * OS2ECP (Octet String To Elliptic Curve Point)
348 *
349 * Deserialize an encoded point. Verifies that the point is on the curve.
350 */
351 EC_Point OS2ECP(const uint8_t bits[], size_t len) const;
352
353 EC_Point OS2ECP(std::span<const uint8_t> encoded_point) const {
354 return this->OS2ECP(encoded_point.data(), encoded_point.size());
355 }
356
357 bool initialized() const { return (m_data != nullptr); }
358
359 /**
360 * Verify EC_Group domain
361 * @returns true if group is valid. false otherwise
362 */
363 bool verify_group(RandomNumberGenerator& rng, bool strong = false) const;
364
365 bool operator==(const EC_Group& other) const;
366
367 EC_Group_Source source() const;
368
369 /**
370 * Return true if this EC_Group was derived from an explicit encoding
371 *
372 * Explicit encoding of groups is deprecated; when support for explicit curves
373 * is removed in a future major release, this function will also be removed.
374 */
375 bool used_explicit_encoding() const { return m_explicit_encoding; }
376
377 /**
378 * Return a set of known named EC groups
379 */
380 static const std::set<std::string>& known_named_groups();
381
382 // Everything below here will be removed in a future release:
383
384 /**
385 * Return if a == -3 mod p
386 */
387 BOTAN_DEPRECATED("Deprecated no replacement") bool a_is_minus_3() const;
388
389 /**
390 * Return if a == 0 mod p
391 */
392 BOTAN_DEPRECATED("Deprecated no replacement") bool a_is_zero() const;
393
394 /*
395 * Reduce x modulo the order
396 */
397 BOTAN_DEPRECATED("Deprecated no replacement") BigInt mod_order(const BigInt& x) const;
398
399 /*
400 * Return inverse of x modulo the order
401 */
402 BOTAN_DEPRECATED("Deprecated no replacement") BigInt inverse_mod_order(const BigInt& x) const;
403
404 /*
405 * Reduce (x*x) modulo the order
406 */
407 BOTAN_DEPRECATED("Deprecated no replacement") BigInt square_mod_order(const BigInt& x) const;
408
409 /*
410 * Reduce (x*y) modulo the order
411 */
412 BOTAN_DEPRECATED("Deprecated no replacement") BigInt multiply_mod_order(const BigInt& x, const BigInt& y) const;
413
414 /*
415 * Reduce (x*y*z) modulo the order
416 */
417 BOTAN_DEPRECATED("Deprecated no replacement")
418 BigInt multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const;
419
420 /*
421 * Return x^3 modulo the order
422 */
423 BOTAN_DEPRECATED("Deprecated no replacement") BigInt cube_mod_order(const BigInt& x) const;
424
425 /**
426 * Return a point on this curve with the affine values x, y
427 */
428 BOTAN_DEPRECATED("Deprecated - use OS2ECP") EC_Point point(const BigInt& x, const BigInt& y) const;
429
430 /**
431 * Return the zero (or infinite) point on this curve
432 */
433 BOTAN_DEPRECATED("Deprecated no replacement") EC_Point zero_point() const;
434
435 BOTAN_DEPRECATED("Just serialize the point and check") size_t point_size(EC_Point_Format format) const;
436
437 /*
438 * For internal use only
439 */
440 static std::shared_ptr<EC_Group_Data> EC_group_info(const OID& oid);
441
442 /*
443 * For internal use only
444 */
445 static size_t clear_registered_curve_data();
446
447 /*
448 * For internal use only
449 */
450 static OID EC_group_identity_from_order(const BigInt& order);
451
452 private:
453 static EC_Group_Data_Map& ec_group_data();
454
455 EC_Group(std::shared_ptr<EC_Group_Data>&& data);
456
457 static std::pair<std::shared_ptr<EC_Group_Data>, bool> BER_decode_EC_group(std::span<const uint8_t> ber,
458 EC_Group_Source source);
459
460 static std::shared_ptr<EC_Group_Data> load_EC_group_info(const char* p,
461 const char* a,
462 const char* b,
463 const char* g_x,
464 const char* g_y,
465 const char* order,
466 const OID& oid);
467
468 // Member data
469 const EC_Group_Data& data() const;
470 std::shared_ptr<EC_Group_Data> m_data;
471 bool m_explicit_encoding = false;
472};
473
474inline bool operator!=(const EC_Group& lhs, const EC_Group& rhs) {
475 return !(lhs == rhs);
476}
477
478} // namespace Botan
479
480#endif
bool initialized() const
Definition ec_group.h:357
EC_Group & operator=(EC_Group &&)=default
EC_Group(const EC_Group &)
bool used_explicit_encoding() const
Definition ec_group.h:375
EC_Point OS2ECP(std::span< const uint8_t > encoded_point) const
Definition ec_group.h:353
EC_Group(EC_Group &&)=default
EC_Group & operator=(const EC_Group &)
std::string name
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition compiler.h:31
#define BOTAN_DEPRECATED(msg)
Definition compiler.h:125
EC_Group_Source
Definition ec_group.h:34
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:648
EC_Group_Encoding
Definition ec_group.h:24