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