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