/src/botan/build/include/botan/ec_group.h
Line | Count | Source (jump to first uncovered line) |
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 <set> |
17 | | |
18 | | namespace Botan { |
19 | | |
20 | | /** |
21 | | * This class represents elliptic curce domain parameters |
22 | | */ |
23 | | enum class EC_Group_Encoding { |
24 | | Explicit, |
25 | | ImplicitCA, |
26 | | NamedCurve, |
27 | | |
28 | | EC_DOMPAR_ENC_EXPLICIT = Explicit, |
29 | | EC_DOMPAR_ENC_IMPLICITCA = ImplicitCA, |
30 | | EC_DOMPAR_ENC_OID = NamedCurve |
31 | | }; |
32 | | |
33 | | enum class EC_Group_Source { |
34 | | Builtin, |
35 | | ExternalSource, |
36 | | }; |
37 | | |
38 | | class CurveGFp; |
39 | | |
40 | | class EC_Group_Data; |
41 | | class 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 | | */ |
49 | | class BOTAN_PUBLIC_API(2,0) EC_Group final |
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 | 5.04k | 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 | 14.3k | EC_Group(const EC_Group&) = default; |
110 | | EC_Group(EC_Group&&) = default; |
111 | | |
112 | 17.9k | EC_Group& operator=(const EC_Group&) = default; |
113 | 2.42k | EC_Group& operator=(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 EC_Point& 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 | 0 | { |
231 | 0 | return multiply_mod_order(x, square_mod_order(x)); |
232 | 0 | } |
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 EC_Point& 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 | | EC_Point 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 | | EC_Point point_multiply(const BigInt& x, const EC_Point& 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 | | EC_Point blinded_base_point_multiply(const BigInt& k, |
267 | | RandomNumberGenerator& rng, |
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, |
280 | | RandomNumberGenerator& rng, |
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 | | EC_Point blinded_var_point_multiply(const EC_Point& point, |
292 | | const BigInt& k, |
293 | | RandomNumberGenerator& rng, |
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 | | EC_Point 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 | | EC_Point 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 | | EC_Point zero_point() const; |
343 | | |
344 | | size_t point_size(EC_Point::Compression_Type format) const; |
345 | | |
346 | | EC_Point OS2ECP(const uint8_t bits[], size_t len) const; |
347 | | |
348 | | template<typename Alloc> |
349 | | EC_Point OS2ECP(const std::vector<uint8_t, Alloc>& vec) const |
350 | 3.19k | { |
351 | 3.19k | return this->OS2ECP(vec.data(), vec.size()); |
352 | 3.19k | } Botan::EC_Point Botan::EC_Group::OS2ECP<std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&) const Line | Count | Source | 350 | 1.92k | { | 351 | 1.92k | return this->OS2ECP(vec.data(), vec.size()); | 352 | 1.92k | } |
Botan::EC_Point Botan::EC_Group::OS2ECP<Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&) const Line | Count | Source | 350 | 1.27k | { | 351 | 1.27k | return this->OS2ECP(vec.data(), vec.size()); | 352 | 1.27k | } |
|
353 | | |
354 | 0 | 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 | | |
407 | | inline bool operator!=(const EC_Group& lhs, |
408 | | const EC_Group& rhs) |
409 | 0 | { |
410 | 0 | return !(lhs == rhs); |
411 | 0 | } |
412 | | |
413 | | // For compatibility with 1.8 |
414 | | typedef EC_Group EC_Domain_Params; |
415 | | |
416 | | } |
417 | | |
418 | | #endif |