/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/asn1_obj.h> |
14 | | #include <botan/ec_point.h> |
15 | | #include <memory> |
16 | | #include <set> |
17 | | #include <span> |
18 | | |
19 | | namespace Botan { |
20 | | |
21 | | /** |
22 | | * This class represents elliptic curce domain parameters |
23 | | */ |
24 | | enum class EC_Group_Encoding { |
25 | | Explicit, |
26 | | ImplicitCA, |
27 | | NamedCurve, |
28 | | |
29 | | EC_DOMPAR_ENC_EXPLICIT = Explicit, |
30 | | EC_DOMPAR_ENC_IMPLICITCA = ImplicitCA, |
31 | | EC_DOMPAR_ENC_OID = NamedCurve |
32 | | }; |
33 | | |
34 | | enum class EC_Group_Source { |
35 | | Builtin, |
36 | | ExternalSource, |
37 | | }; |
38 | | |
39 | | class EC_Group_Data; |
40 | | class 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 | | */ |
48 | | class BOTAN_PUBLIC_API(2, 0) EC_Group final { |
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 | | */ |
101 | | EC_Group(); |
102 | | |
103 | | ~EC_Group(); |
104 | | |
105 | | EC_Group(const EC_Group&) = default; |
106 | | EC_Group(EC_Group&&) = default; |
107 | | |
108 | | EC_Group& operator=(const EC_Group&) = default; |
109 | | EC_Group& operator=(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 | 0 | 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, |
282 | | RandomNumberGenerator& rng, |
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 | 0 | EC_Point OS2ECP(std::span<const uint8_t> encoded_point) const { |
338 | 0 | return this->OS2ECP(encoded_point.data(), encoded_point.size()); |
339 | 0 | } |
340 | | |
341 | 0 | 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 a set of known named EC groups |
355 | | */ |
356 | | static const std::set<std::string>& known_named_groups(); |
357 | | |
358 | | /* |
359 | | * For internal use only |
360 | | */ |
361 | | static std::shared_ptr<EC_Group_Data> EC_group_info(const OID& oid); |
362 | | |
363 | | /* |
364 | | * For internal use only |
365 | | */ |
366 | | static size_t clear_registered_curve_data(); |
367 | | |
368 | | /* |
369 | | * For internal use only |
370 | | */ |
371 | | static OID EC_group_identity_from_order(const BigInt& order); |
372 | | |
373 | | private: |
374 | | static EC_Group_Data_Map& ec_group_data(); |
375 | | |
376 | | static std::shared_ptr<EC_Group_Data> BER_decode_EC_group(const uint8_t bits[], |
377 | | size_t len, |
378 | | EC_Group_Source source); |
379 | | |
380 | | static std::shared_ptr<EC_Group_Data> load_EC_group_info(const char* p, |
381 | | const char* a, |
382 | | const char* b, |
383 | | const char* g_x, |
384 | | const char* g_y, |
385 | | const char* order, |
386 | | const OID& oid); |
387 | | |
388 | | // Member data |
389 | | const EC_Group_Data& data() const; |
390 | | std::shared_ptr<EC_Group_Data> m_data; |
391 | | }; |
392 | | |
393 | 0 | inline bool operator!=(const EC_Group& lhs, const EC_Group& rhs) { return !(lhs == rhs); } |
394 | | |
395 | | } // namespace Botan |
396 | | |
397 | | #endif |