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