/src/botan/build/include/public/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,2024 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/bigint.h> |
15 | | #include <botan/ec_apoint.h> |
16 | | #include <botan/ec_point_format.h> |
17 | | #include <botan/ec_scalar.h> |
18 | | #include <memory> |
19 | | #include <set> |
20 | | #include <span> |
21 | | |
22 | | #if defined(BOTAN_HAS_LEGACY_EC_POINT) |
23 | | #include <botan/ec_point.h> |
24 | | #endif |
25 | | |
26 | | namespace Botan { |
27 | | |
28 | | /** |
29 | | * This enum indicates the method used to encode the EC parameters |
30 | | * |
31 | | * @warning All support for explicit or implicit domain encodings |
32 | | * will be removed in Botan4. Only named curves will be supported. |
33 | | * |
34 | | * TODO(Botan4) remove this enum |
35 | | */ |
36 | | enum class EC_Group_Encoding { |
37 | | Explicit, |
38 | | ImplicitCA, |
39 | | NamedCurve, |
40 | | |
41 | | EC_DOMPAR_ENC_EXPLICIT = Explicit, |
42 | | EC_DOMPAR_ENC_IMPLICITCA = ImplicitCA, |
43 | | EC_DOMPAR_ENC_OID = NamedCurve |
44 | | }; |
45 | | |
46 | | /** |
47 | | * This enum indicates the source of the elliptic curve parameters |
48 | | * in use. |
49 | | * |
50 | | * Builtin means the curve is a known standard one which was compiled |
51 | | * in the library. |
52 | | * |
53 | | * ExternalSource means the curve parameters came from either an explicit |
54 | | * curve encoding or an application defined curve. |
55 | | */ |
56 | | enum class EC_Group_Source { |
57 | | Builtin, |
58 | | ExternalSource, |
59 | | }; |
60 | | |
61 | | /** |
62 | | * Enum indicating the way the group in question is implemented |
63 | | * |
64 | | * This is returned by EC_Group::engine |
65 | | */ |
66 | | enum class EC_Group_Engine { |
67 | | /// Using per curve implementation; fastest available |
68 | | Optimized, |
69 | | /// A generic implementation that handles many curves in one implementation |
70 | | Generic, |
71 | | /// The old implementation, used as a fallback if none of the other |
72 | | /// implementations can be used |
73 | | /// TODO(Botan4) remove this |
74 | | Legacy, |
75 | | }; |
76 | | |
77 | | class EC_Mul2Table_Data; |
78 | | class EC_Group_Data; |
79 | | class EC_Group_Data_Map; |
80 | | |
81 | | /** |
82 | | * Class representing an elliptic curve |
83 | | * |
84 | | * The internal representation is stored in a shared_ptr, so copying an |
85 | | * EC_Group is inexpensive. |
86 | | */ |
87 | | class BOTAN_PUBLIC_API(2, 0) EC_Group final { |
88 | | public: |
89 | | /** |
90 | | * Construct elliptic curve from the specified parameters |
91 | | * |
92 | | * This is used for example to create custom (application-specific) curves. |
93 | | * |
94 | | * Some build configurations do not support application specific curves, in |
95 | | * which case this constructor will throw an exception. You can check for |
96 | | * this situation beforehand using the function |
97 | | * EC_Group::supports_application_specific_group() |
98 | | * |
99 | | * @param p the elliptic curve p |
100 | | * @param a the elliptic curve a param |
101 | | * @param b the elliptic curve b param |
102 | | * @param base_x the x coordinate of the base point |
103 | | * @param base_y the y coordinate of the base point |
104 | | * @param order the order of the base point |
105 | | * @param cofactor the cofactor |
106 | | * @param oid an optional OID used to identify this curve |
107 | | * |
108 | | * @warning This constructor is deprecated and will be removed in Botan 4 |
109 | | * |
110 | | * @warning support for cofactors > 1 is deprecated and will be removed |
111 | | * |
112 | | * @warning support for prime fields > 521 bits is deprecated and |
113 | | * will be removed. |
114 | | * |
115 | | * @warning Support for explicitly encoded curve parameters is deprecated. |
116 | | * An OID must be assigned. |
117 | | */ |
118 | | BOTAN_DEPRECATED("Use alternate constructor") |
119 | | EC_Group(const BigInt& p, |
120 | | const BigInt& a, |
121 | | const BigInt& b, |
122 | | const BigInt& base_x, |
123 | | const BigInt& base_y, |
124 | | const BigInt& order, |
125 | | const BigInt& cofactor, |
126 | | const OID& oid = OID()); |
127 | | |
128 | | /** |
129 | | * Construct elliptic curve from the specified parameters |
130 | | * |
131 | | * This is used for example to create custom (application-specific) curves. |
132 | | * |
133 | | * Some build configurations do not support application specific curves, in |
134 | | * which case this constructor will throw an exception. You can check for |
135 | | * this situation beforehand using the function |
136 | | * EC_Group::supports_application_specific_group() |
137 | | * |
138 | | * Unlike the deprecated constructor, this constructor imposes additional |
139 | | * restrictions on the parameters, namely: |
140 | | * |
141 | | * - An object identifier must be provided |
142 | | * |
143 | | * - The prime must be at least 192 bits and at most 512 bits, and a multiple |
144 | | * of 32 bits. Currently, as long as BOTAN_DISABLE_DEPRECATED_FEATURES is not |
145 | | * set, this constructor accepts primes as small as 128 bits - this lower |
146 | | * bound will be removed in the next major release. |
147 | | * |
148 | | * - As an extension of the above restriction, the prime can also be exactly |
149 | | * the 521-bit Mersenne prime (2**521-1) or exactly the 239-bit prime used in |
150 | | * X9.62 239 bit groups (2**239 - 2**143 - 2**95 + 2**47 - 1) |
151 | | * |
152 | | * - The prime must be congruent to 3 modulo 4 |
153 | | * |
154 | | * - The group order must have the same bit length as the prime. It is allowed |
155 | | * for the order to be larger than p, but they must have the same bit length. |
156 | | * |
157 | | * - Only prime order curves (with cofactor == 1) are allowed |
158 | | * |
159 | | * @warning use only elliptic curve parameters that you trust |
160 | | * |
161 | | * @param oid an object identifier used to identify this curve |
162 | | * @param p the elliptic curve prime (at most 521 bits) |
163 | | * @param a the elliptic curve a param |
164 | | * @param b the elliptic curve b param |
165 | | * @param base_x the x coordinate of the group generator |
166 | | * @param base_y the y coordinate of the group generator |
167 | | * @param order the order of the group |
168 | | */ |
169 | | EC_Group(const OID& oid, |
170 | | const BigInt& p, |
171 | | const BigInt& a, |
172 | | const BigInt& b, |
173 | | const BigInt& base_x, |
174 | | const BigInt& base_y, |
175 | | const BigInt& order); |
176 | | |
177 | | /** |
178 | | * Decode a BER encoded ECC domain parameter set |
179 | | * @param ber the bytes of the BER encoding |
180 | | */ |
181 | | explicit EC_Group(std::span<const uint8_t> ber); |
182 | | |
183 | | BOTAN_DEPRECATED("Use EC_Group(std::span)") |
184 | 0 | EC_Group(const uint8_t ber[], size_t ber_len) : EC_Group(std::span{ber, ber_len}) {} |
185 | | |
186 | | /** |
187 | | * Create an EC domain by OID (or throw if unknown) |
188 | | * @param oid the OID of the EC domain to create |
189 | | */ |
190 | 0 | BOTAN_DEPRECATED("Use EC_Group::from_OID") explicit EC_Group(const OID& oid) { *this = EC_Group::from_OID(oid); } |
191 | | |
192 | | /** |
193 | | * Create an EC domain from PEM encoding (as from PEM_encode()), or |
194 | | * from an OID name (eg "secp256r1", or "1.2.840.10045.3.1.7") |
195 | | * @param pem_or_oid PEM-encoded data, or an OID |
196 | | * |
197 | | * @warning Support for PEM in this function is deprecated. Use |
198 | | * EC_Group::from_PEM or EC_Group::from_OID or EC_Group::from_name |
199 | | */ |
200 | | BOTAN_DEPRECATED("Use EC_Group::from_{name,OID,PEM}") explicit EC_Group(std::string_view pem_or_oid); |
201 | | |
202 | | /** |
203 | | * Initialize an EC group from the PEM/ASN.1 encoding |
204 | | */ |
205 | | static EC_Group from_PEM(std::string_view pem); |
206 | | |
207 | | /** |
208 | | * Initialize an EC group from a group named by an object identifier |
209 | | */ |
210 | | static EC_Group from_OID(const OID& oid); |
211 | | |
212 | | /** |
213 | | * Initialize an EC group from a group common name (eg "secp256r1") |
214 | | */ |
215 | | static EC_Group from_name(std::string_view name); |
216 | | |
217 | 0 | BOTAN_DEPRECATED("Use EC_Group::from_PEM") static EC_Group EC_Group_from_PEM(std::string_view pem) { |
218 | 0 | return EC_Group::from_PEM(pem); |
219 | 0 | } |
220 | | |
221 | | /** |
222 | | * Create an uninitialized EC_Group |
223 | | */ |
224 | | BOTAN_DEPRECATED("Deprecated no replacement") EC_Group(); |
225 | | |
226 | | ~EC_Group(); |
227 | | |
228 | | EC_Group(const EC_Group&); |
229 | 5.35k | EC_Group(EC_Group&&) = default; |
230 | | |
231 | | EC_Group& operator=(const EC_Group&); |
232 | | EC_Group& operator=(EC_Group&&) = default; |
233 | | |
234 | 0 | bool initialized() const { return (m_data != nullptr); } |
235 | | |
236 | | /** |
237 | | * Verify EC_Group domain |
238 | | * @returns true if group is valid. false otherwise |
239 | | */ |
240 | | bool verify_group(RandomNumberGenerator& rng, bool strong = false) const; |
241 | | |
242 | | bool operator==(const EC_Group& other) const; |
243 | | |
244 | | EC_Group_Source source() const; |
245 | | |
246 | | /** |
247 | | * Return true if in this build configuration it is possible to |
248 | | * register an application specific elliptic curve. |
249 | | */ |
250 | | static bool supports_application_specific_group(); |
251 | | |
252 | | /** |
253 | | * Return true if in this build configuration EC_Group::from_name(name) will succeed |
254 | | */ |
255 | | static bool supports_named_group(std::string_view name); |
256 | | |
257 | | /** |
258 | | * Return true if this EC_Group was derived from an explicit encoding |
259 | | * |
260 | | * Explicit encoding of groups is deprecated; when support for explicit curves |
261 | | * is removed in a future major release, this function will also be removed. |
262 | | */ |
263 | 0 | bool used_explicit_encoding() const { return m_explicit_encoding; } |
264 | | |
265 | | /** |
266 | | * Return how this EC_Group is implemented under the hood |
267 | | * |
268 | | * This is mostly useful for diagnostic or debugging purposes |
269 | | */ |
270 | | EC_Group_Engine engine() const; |
271 | | |
272 | | /** |
273 | | * Return a set of known named EC groups |
274 | | * |
275 | | * This returns the set of groups for which from_name should succeed |
276 | | * Note that the set of included groups can vary based on the |
277 | | * build configuration. |
278 | | */ |
279 | | static const std::set<std::string>& known_named_groups(); |
280 | | |
281 | | /** |
282 | | * Create the DER encoding of this domain |
283 | | * @param form of encoding to use |
284 | | * @returns the group information encoded as DER |
285 | | */ |
286 | | BOTAN_DEPRECATED("Use the variant that does not take EC_Group_Encoding") |
287 | | std::vector<uint8_t> DER_encode(EC_Group_Encoding form) const; |
288 | | |
289 | | /** |
290 | | * Create the DER encoding of this domain, using namedCurve format |
291 | | * @returns the group information encoded as DER |
292 | | */ |
293 | | std::vector<uint8_t> DER_encode() const; |
294 | | |
295 | | /** |
296 | | * Return the PEM encoding (always in explicit form) |
297 | | * @return string containing PEM data |
298 | | */ |
299 | | std::string PEM_encode() const; |
300 | | |
301 | | /** |
302 | | * Return the size of p in bits (same as get_p().bits()) |
303 | | */ |
304 | | size_t get_p_bits() const; |
305 | | |
306 | | /** |
307 | | * Return the size of p in bytes (same as get_p().bytes()) |
308 | | */ |
309 | | size_t get_p_bytes() const; |
310 | | |
311 | | /** |
312 | | * Return the size of group order in bits (same as get_order().bits()) |
313 | | */ |
314 | | size_t get_order_bits() const; |
315 | | |
316 | | /** |
317 | | * Return the size of the group order in bytes (same as get_order().bytes()) |
318 | | */ |
319 | | size_t get_order_bytes() const; |
320 | | |
321 | | /// Table for computing g*x + h*y |
322 | | class BOTAN_PUBLIC_API(3, 6) Mul2Table final { |
323 | | public: |
324 | | /** |
325 | | * Create a table for computing g*x + h*y |
326 | | */ |
327 | | Mul2Table(const EC_AffinePoint& h); |
328 | | |
329 | | /** |
330 | | * Return the elliptic curve point g*x + h*y |
331 | | * |
332 | | * Where g is the group generator and h is the value passed to the constructor |
333 | | * |
334 | | * Returns nullopt if g*x + h*y was the point at infinity |
335 | | * |
336 | | * @warning this function is variable time with respect to x and y |
337 | | */ |
338 | | std::optional<EC_AffinePoint> mul2_vartime(const EC_Scalar& x, const EC_Scalar& y) const; |
339 | | |
340 | | /** |
341 | | * Check if v equals the x coordinate of g*x + h*y reduced modulo the order |
342 | | * |
343 | | * Where g is the group generator and h is the value passed to the constructor |
344 | | * |
345 | | * Returns false if unequal, including if g*x + h*y was the point at infinity |
346 | | * |
347 | | * @warning this function is variable time with respect to x and y |
348 | | */ |
349 | | bool mul2_vartime_x_mod_order_eq(const EC_Scalar& v, const EC_Scalar& x, const EC_Scalar& y) const; |
350 | | |
351 | | /** |
352 | | * Check if v equals the x coordinate of g*x*c + h*y*c reduced modulo the order |
353 | | * |
354 | | * Where g is the group generator and h is the value passed to the constructor |
355 | | * |
356 | | * Returns false if unequal, including if g*x*c + h*y*c was the point at infinity |
357 | | * |
358 | | * @warning this function is variable time with respect to x and y |
359 | | */ |
360 | | bool mul2_vartime_x_mod_order_eq(const EC_Scalar& v, |
361 | | const EC_Scalar& c, |
362 | | const EC_Scalar& x, |
363 | | const EC_Scalar& y) const; |
364 | | |
365 | | ~Mul2Table(); |
366 | | |
367 | | private: |
368 | | std::unique_ptr<EC_Mul2Table_Data> m_tbl; |
369 | | }; |
370 | | |
371 | | /** |
372 | | * Return the OID of these domain parameters |
373 | | * @result the OID |
374 | | */ |
375 | | const OID& get_curve_oid() const; |
376 | | |
377 | | /** |
378 | | * Return the prime modulus of the field |
379 | | */ |
380 | | const BigInt& get_p() const; |
381 | | |
382 | | /** |
383 | | * Return the a parameter of the elliptic curve equation |
384 | | */ |
385 | | const BigInt& get_a() const; |
386 | | |
387 | | /** |
388 | | * Return the b parameter of the elliptic curve equation |
389 | | */ |
390 | | const BigInt& get_b() const; |
391 | | |
392 | | /** |
393 | | * Return the x coordinate of the base point |
394 | | */ |
395 | | const BigInt& get_g_x() const; |
396 | | |
397 | | /** |
398 | | * Return the y coordinate of the base point |
399 | | */ |
400 | | const BigInt& get_g_y() const; |
401 | | |
402 | | /** |
403 | | * Return the order of the base point |
404 | | * @result order of the base point |
405 | | */ |
406 | | const BigInt& get_order() const; |
407 | | |
408 | | /** |
409 | | * Return the cofactor |
410 | | * @result the cofactor |
411 | | * TODO(Botan4): Remove this |
412 | | */ |
413 | | const BigInt& get_cofactor() const; |
414 | | |
415 | | /** |
416 | | * Return true if the cofactor is > 1 |
417 | | * TODO(Botan4): Remove this |
418 | | */ |
419 | | bool has_cofactor() const; |
420 | | |
421 | | /* |
422 | | * For internal use only |
423 | | * TODO(Botan4): Move this to an internal header |
424 | | */ |
425 | | static std::shared_ptr<EC_Group_Data> EC_group_info(const OID& oid); |
426 | | |
427 | | /* |
428 | | * For internal use only |
429 | | * |
430 | | * @warning this invalidates pointers and can cause memory corruption. |
431 | | * This function exists only to be called in tests. |
432 | | * |
433 | | * TODO(Botan4): Move this to an internal header |
434 | | */ |
435 | | static size_t clear_registered_curve_data(); |
436 | | |
437 | | /* |
438 | | * For internal use only |
439 | | * TODO(Botan4): Move this to an internal header |
440 | | */ |
441 | | static OID EC_group_identity_from_order(const BigInt& order); |
442 | | |
443 | | /* |
444 | | * For internal use only |
445 | | */ |
446 | 9.99k | const std::shared_ptr<EC_Group_Data>& _data() const { return m_data; } |
447 | | |
448 | | #if defined(BOTAN_HAS_LEGACY_EC_POINT) |
449 | | /** |
450 | | * Check if y is a plausible point on the curve |
451 | | * |
452 | | * In particular, checks that it is a point on the curve, not infinity, |
453 | | * and that it has order matching the group. |
454 | | */ |
455 | | bool verify_public_element(const EC_Point& y) const; |
456 | | |
457 | | /** |
458 | | * OS2ECP (Octet String To Elliptic Curve Point) |
459 | | * |
460 | | * Deserialize an encoded point. Verifies that the point is on the curve. |
461 | | */ |
462 | 0 | BOTAN_DEPRECATED("Use EC_AffinePoint::deserialize") EC_Point OS2ECP(const uint8_t bits[], size_t len) const { |
463 | 0 | return EC_AffinePoint(*this, std::span{bits, len}).to_legacy_point(); |
464 | 0 | } |
465 | | |
466 | | BOTAN_DEPRECATED("Use EC_AffinePoint::deserialize") |
467 | 0 | EC_Point OS2ECP(std::span<const uint8_t> encoded_point) const { |
468 | 0 | return EC_AffinePoint(*this, encoded_point).to_legacy_point(); |
469 | 0 | } |
470 | | |
471 | | /** |
472 | | * Return group base point |
473 | | * @result base point |
474 | | */ |
475 | | BOTAN_DEPRECATED("Use EC_AffinePoint::generator") const EC_Point& get_base_point() const; |
476 | | |
477 | | // Everything below here will be removed in a future release: |
478 | | |
479 | | /** |
480 | | * Return the canonical group generator |
481 | | * @result standard generator of the curve |
482 | | */ |
483 | | BOTAN_DEPRECATED("Use EC_AffinePoint::generator") const EC_Point& generator() const; |
484 | | |
485 | | /** |
486 | | * Multi exponentiate. Not constant time. |
487 | | * @return base_point*x + h*y |
488 | | */ |
489 | | BOTAN_DEPRECATED("Use EC_Group::Mul2Table") |
490 | 0 | EC_Point point_multiply(const BigInt& x_bn, const EC_Point& h_pt, const BigInt& y_bn) const { |
491 | 0 | auto x = EC_Scalar::from_bigint(*this, x_bn); |
492 | 0 | auto y = EC_Scalar::from_bigint(*this, y_bn); |
493 | 0 | auto h = EC_AffinePoint(*this, h_pt); |
494 | 0 |
|
495 | 0 | Mul2Table gh_mul(h); |
496 | 0 |
|
497 | 0 | if(auto r = gh_mul.mul2_vartime(x, y)) { |
498 | 0 | return r->to_legacy_point(); |
499 | 0 | } else { |
500 | 0 | return EC_AffinePoint::identity(*this).to_legacy_point(); |
501 | 0 | } |
502 | 0 | } |
503 | | |
504 | | /** |
505 | | * Blinded point multiplication, attempts resistance to side channels |
506 | | * @param k_bn the scalar |
507 | | * @param rng a random number generator |
508 | | * @return base_point*k |
509 | | */ |
510 | | BOTAN_DEPRECATED("Use EC_AffinePoint and EC_Scalar") |
511 | 0 | EC_Point blinded_base_point_multiply(const BigInt& k_bn, RandomNumberGenerator& rng, std::vector<BigInt>&) const { |
512 | 0 | auto k = EC_Scalar::from_bigint(*this, k_bn); |
513 | 0 | auto pt = EC_AffinePoint::g_mul(k, rng); |
514 | 0 | return pt.to_legacy_point(); |
515 | 0 | } |
516 | | |
517 | | /** |
518 | | * Blinded point multiplication, attempts resistance to side channels |
519 | | * Returns just the x coordinate of the point |
520 | | * |
521 | | * @param k_bn the scalar |
522 | | * @param rng a random number generator |
523 | | * @return x coordinate of base_point*k |
524 | | */ |
525 | | BOTAN_DEPRECATED("Use EC_AffinePoint and EC_Scalar") |
526 | 0 | BigInt blinded_base_point_multiply_x(const BigInt& k_bn, RandomNumberGenerator& rng, std::vector<BigInt>&) const { |
527 | 0 | auto k = EC_Scalar::from_bigint(*this, k_bn); |
528 | 0 | return BigInt(EC_AffinePoint::g_mul(k, rng).x_bytes()); |
529 | 0 | } |
530 | | |
531 | | /** |
532 | | * Blinded point multiplication, attempts resistance to side channels |
533 | | * @param point input point |
534 | | * @param k_bn the scalar |
535 | | * @param rng a random number generator |
536 | | * @return point*k |
537 | | */ |
538 | | BOTAN_DEPRECATED("Use EC_AffinePoint and EC_Scalar") |
539 | | EC_Point blinded_var_point_multiply(const EC_Point& point, |
540 | | const BigInt& k_bn, |
541 | | RandomNumberGenerator& rng, |
542 | 50 | std::vector<BigInt>&) const { |
543 | 50 | auto k = EC_Scalar::from_bigint(*this, k_bn); |
544 | 50 | auto pt = EC_AffinePoint(*this, point); |
545 | 50 | return pt.mul(k, rng).to_legacy_point(); |
546 | 50 | } |
547 | | |
548 | | /** |
549 | | * Return a random scalar ie an integer in [1,order) |
550 | | */ |
551 | 0 | BOTAN_DEPRECATED("Use EC_Scalar::random") BigInt random_scalar(RandomNumberGenerator& rng) const { |
552 | 0 | return EC_Scalar::random(*this, rng).to_bigint(); |
553 | 0 | } |
554 | | |
555 | | /** |
556 | | * Hash onto the curve. |
557 | | * For some curve types no mapping is currently available, in this |
558 | | * case this function will throw an exception. |
559 | | * |
560 | | * @param hash_fn the hash function to use (typically "SHA-256" or "SHA-512") |
561 | | * @param input the input to hash |
562 | | * @param input_len length of input in bytes |
563 | | * @param domain_sep a domain seperator |
564 | | * @param domain_sep_len length of domain_sep in bytes |
565 | | * @param random_oracle if the mapped point must be uniform (use |
566 | | "true" here unless you know what you are doing) |
567 | | */ |
568 | | BOTAN_DEPRECATED("Use EC_AffinePoint") |
569 | | EC_Point hash_to_curve(std::string_view hash_fn, |
570 | | const uint8_t input[], |
571 | | size_t input_len, |
572 | | const uint8_t domain_sep[], |
573 | | size_t domain_sep_len, |
574 | 0 | bool random_oracle = true) const { |
575 | 0 | auto inp = std::span{input, input_len}; |
576 | 0 | auto dst = std::span{domain_sep, domain_sep_len}; |
577 | 0 |
|
578 | 0 | if(random_oracle) { |
579 | 0 | return EC_AffinePoint::hash_to_curve_ro(*this, hash_fn, inp, dst).to_legacy_point(); |
580 | 0 | } else { |
581 | 0 | return EC_AffinePoint::hash_to_curve_nu(*this, hash_fn, inp, dst).to_legacy_point(); |
582 | 0 | } |
583 | 0 | } |
584 | | |
585 | | /** |
586 | | * Hash onto the curve. |
587 | | * For some curve types no mapping is currently available, in this |
588 | | * case this function will throw an exception. |
589 | | * |
590 | | * @param hash_fn the hash function to use (typically "SHA-256" or "SHA-512") |
591 | | * @param input the input to hash |
592 | | * @param input_len length of input in bytes |
593 | | * @param domain_sep a domain seperator |
594 | | * @param random_oracle if the mapped point must be uniform (use |
595 | | "true" here unless you know what you are doing) |
596 | | */ |
597 | | BOTAN_DEPRECATED("Use EC_AffinePoint") |
598 | | EC_Point hash_to_curve(std::string_view hash_fn, |
599 | | const uint8_t input[], |
600 | | size_t input_len, |
601 | | std::string_view domain_sep, |
602 | 0 | bool random_oracle = true) const { |
603 | 0 | auto inp = std::span{input, input_len}; |
604 | 0 | auto dst = std::span{reinterpret_cast<const uint8_t*>(domain_sep.data()), domain_sep.size()}; |
605 | 0 |
|
606 | 0 | if(random_oracle) { |
607 | 0 | return EC_AffinePoint::hash_to_curve_ro(*this, hash_fn, inp, dst).to_legacy_point(); |
608 | 0 | } else { |
609 | 0 | return EC_AffinePoint::hash_to_curve_nu(*this, hash_fn, inp, dst).to_legacy_point(); |
610 | 0 | } |
611 | 0 | } |
612 | | |
613 | | /** |
614 | | * Return a point on this curve with the affine values x, y |
615 | | */ |
616 | 2.93k | BOTAN_DEPRECATED("Deprecated - use EC_AffinePoint") EC_Point point(const BigInt& x, const BigInt& y) const { |
617 | 2.93k | if(auto pt = EC_AffinePoint::from_bigint_xy(*this, x, y)) { |
618 | 1.56k | return pt->to_legacy_point(); |
619 | 1.56k | } else { |
620 | 1.36k | throw Decoding_Error("Invalid x/y coordinates for elliptic curve point"); |
621 | 1.36k | } |
622 | 2.93k | } |
623 | | |
624 | | /** |
625 | | * Return the zero (or infinite) point on this curve |
626 | | */ |
627 | 0 | BOTAN_DEPRECATED("Deprecated no replacement") EC_Point zero_point() const { |
628 | 0 | return EC_AffinePoint::identity(*this).to_legacy_point(); |
629 | 0 | } |
630 | | #endif |
631 | | |
632 | | /** |
633 | | * Return if a == -3 mod p |
634 | | */ |
635 | 0 | BOTAN_DEPRECATED("Deprecated no replacement") bool a_is_minus_3() const { return get_a() + 3 == get_p(); } |
636 | | |
637 | | /** |
638 | | * Return if a == 0 mod p |
639 | | */ |
640 | 0 | BOTAN_DEPRECATED("Deprecated no replacement") bool a_is_zero() const { return get_a().is_zero(); } |
641 | | |
642 | | /* |
643 | | * Reduce x modulo the order |
644 | | */ |
645 | 0 | BOTAN_DEPRECATED("Use EC_Scalar") BigInt mod_order(const BigInt& x) const { |
646 | 0 | return EC_Scalar::from_bytes_mod_order(*this, x.serialize()).to_bigint(); |
647 | 0 | } |
648 | | |
649 | | /* |
650 | | * Return inverse of x modulo the order |
651 | | */ |
652 | 0 | BOTAN_DEPRECATED("Use EC_Scalar") BigInt inverse_mod_order(const BigInt& x) const { |
653 | 0 | return EC_Scalar::from_bigint(*this, x).invert().to_bigint(); |
654 | 0 | } |
655 | | |
656 | | /* |
657 | | * Reduce (x*x) modulo the order |
658 | | */ |
659 | 0 | BOTAN_DEPRECATED("Use EC_Scalar") BigInt square_mod_order(const BigInt& x) const { |
660 | 0 | auto xs = EC_Scalar::from_bigint(*this, x); |
661 | 0 | xs.square_self(); |
662 | 0 | return xs.to_bigint(); |
663 | 0 | } |
664 | | |
665 | | /* |
666 | | * Reduce (x*y) modulo the order |
667 | | */ |
668 | 0 | BOTAN_DEPRECATED("Use EC_Scalar") BigInt multiply_mod_order(const BigInt& x, const BigInt& y) const { |
669 | 0 | auto xs = EC_Scalar::from_bigint(*this, x); |
670 | 0 | auto ys = EC_Scalar::from_bigint(*this, y); |
671 | 0 | return (xs * ys).to_bigint(); |
672 | 0 | } |
673 | | |
674 | | /* |
675 | | * Reduce (x*y*z) modulo the order |
676 | | */ |
677 | | BOTAN_DEPRECATED("Use EC_Scalar") |
678 | 0 | BigInt multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const { |
679 | 0 | auto xs = EC_Scalar::from_bigint(*this, x); |
680 | 0 | auto ys = EC_Scalar::from_bigint(*this, y); |
681 | 0 | auto zs = EC_Scalar::from_bigint(*this, z); |
682 | 0 | return (xs * ys * zs).to_bigint(); |
683 | 0 | } |
684 | | |
685 | | /* |
686 | | * Return x^3 modulo the order |
687 | | */ |
688 | 0 | BOTAN_DEPRECATED("Deprecated no replacement") BigInt cube_mod_order(const BigInt& x) const { |
689 | 0 | auto xs = EC_Scalar::from_bigint(*this, x); |
690 | 0 | return (xs * xs * xs).to_bigint(); |
691 | 0 | } |
692 | | |
693 | 0 | BOTAN_DEPRECATED("Just serialize the point and check") size_t point_size(EC_Point_Format format) const { |
694 | 0 | // Hybrid and standard format are (x,y), compressed is y, +1 format byte |
695 | 0 | if(format == EC_Point_Format::Compressed) { |
696 | 0 | return (1 + get_p_bytes()); |
697 | 0 | } else { |
698 | 0 | return (1 + 2 * get_p_bytes()); |
699 | 0 | } |
700 | 0 | } |
701 | | |
702 | | private: |
703 | | static EC_Group_Data_Map& ec_group_data(); |
704 | | |
705 | | EC_Group(std::shared_ptr<EC_Group_Data>&& data); |
706 | | |
707 | | static std::pair<std::shared_ptr<EC_Group_Data>, bool> BER_decode_EC_group(std::span<const uint8_t> ber, |
708 | | EC_Group_Source source); |
709 | | |
710 | | static std::shared_ptr<EC_Group_Data> load_EC_group_info(const char* p, |
711 | | const char* a, |
712 | | const char* b, |
713 | | const char* g_x, |
714 | | const char* g_y, |
715 | | const char* order, |
716 | | const OID& oid); |
717 | | |
718 | | const EC_Group_Data& data() const; |
719 | | |
720 | | // Member data |
721 | | std::shared_ptr<EC_Group_Data> m_data; |
722 | | bool m_explicit_encoding = false; |
723 | | }; |
724 | | |
725 | 0 | inline bool operator!=(const EC_Group& lhs, const EC_Group& rhs) { |
726 | 0 | return !(lhs == rhs); |
727 | 0 | } |
728 | | |
729 | | } // namespace Botan |
730 | | |
731 | | #endif |