Coverage Report

Created: 2026-02-14 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/build/include/public/botan/ec_group.h
Line
Count
Source
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 : uint8_t {
37
   Explicit = 0,
38
   ImplicitCA = 1,
39
   NamedCurve = 2,
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 : uint8_t {
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 : uint8_t {
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
810
      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 it is possible to
254
      * register an application specific elliptic curve with a cofactor
255
      * larger than 1.
256
      */
257
      static bool supports_application_specific_group_with_cofactor();
258
259
      /**
260
      * Return true if in this build configuration EC_Group::from_name(name) will succeed
261
      */
262
      static bool supports_named_group(std::string_view name);
263
264
      /**
265
      * Return true if this EC_Group was derived from an explicit encoding
266
      *
267
      * Explicit encoding of groups is deprecated; when support for explicit curves
268
      * is removed in a future major release, this function will also be removed.
269
      */
270
0
      bool used_explicit_encoding() const { return m_explicit_encoding; }
271
272
      /**
273
      * Return how this EC_Group is implemented under the hood
274
      *
275
      * This is mostly useful for diagnostic or debugging purposes
276
      */
277
      EC_Group_Engine engine() const;
278
279
      /**
280
      * Return a set of known named EC groups
281
      *
282
      * This returns the set of groups for which from_name should succeed
283
      * Note that the set of included groups can vary based on the
284
      * build configuration.
285
      */
286
      static const std::set<std::string>& known_named_groups();
287
288
      /**
289
      * Create the DER encoding of this domain
290
      * @param form of encoding to use
291
      * @returns the group information encoded as DER
292
      */
293
      BOTAN_DEPRECATED("Use the variant that does not take EC_Group_Encoding")
294
      std::vector<uint8_t> DER_encode(EC_Group_Encoding form) const;
295
296
      /**
297
      * Create the DER encoding of this domain, using namedCurve format
298
      * @returns the group information encoded as DER
299
      */
300
      std::vector<uint8_t> DER_encode() const;
301
302
      /**
303
      * Return the PEM encoding
304
      * @return string containing PEM data
305
      *
306
      * @warning In Botan4 the form parameter will be removed and only
307
      * namedCurve will be supported
308
      *
309
      * TODO(Botan4) remove the argument
310
      */
311
      std::string PEM_encode(EC_Group_Encoding form = EC_Group_Encoding::Explicit) const;
312
313
      /**
314
      * Return the size of p in bits (same as get_p().bits())
315
      */
316
      size_t get_p_bits() const;
317
318
      /**
319
      * Return the size of p in bytes (same as get_p().bytes())
320
      */
321
      size_t get_p_bytes() const;
322
323
      /**
324
      * Return the size of group order in bits (same as get_order().bits())
325
      */
326
      size_t get_order_bits() const;
327
328
      /**
329
      * Return the size of the group order in bytes (same as get_order().bytes())
330
      */
331
      size_t get_order_bytes() const;
332
333
      /// Table for computing g*x + h*y
334
      class BOTAN_PUBLIC_API(3, 6) Mul2Table final {
335
         public:
336
            /**
337
            * Create a table for computing g*x + h*y
338
            */
339
            BOTAN_FUTURE_EXPLICIT Mul2Table(const EC_AffinePoint& h);
340
341
            /**
342
            * Return the elliptic curve point g*x + h*y
343
            *
344
            * Where g is the group generator and h is the value passed to the constructor
345
            *
346
            * Returns nullopt if g*x + h*y was the point at infinity
347
            *
348
            * @warning this function is variable time with respect to x and y
349
            */
350
            std::optional<EC_AffinePoint> mul2_vartime(const EC_Scalar& x, const EC_Scalar& y) const;
351
352
            /**
353
            * Check if v equals the x coordinate of g*x + h*y reduced modulo the order
354
            *
355
            * Where g is the group generator and h is the value passed to the constructor
356
            *
357
            * Returns false if unequal, including if g*x + h*y was the point at infinity
358
            *
359
            * @warning this function is variable time with respect to x and y
360
            */
361
            bool mul2_vartime_x_mod_order_eq(const EC_Scalar& v, const EC_Scalar& x, const EC_Scalar& y) const;
362
363
            /**
364
            * Check if v equals the x coordinate of g*x*c + h*y*c reduced modulo the order
365
            *
366
            * Where g is the group generator and h is the value passed to the constructor
367
            *
368
            * Returns false if unequal, including if g*x*c + h*y*c was the point at infinity
369
            *
370
            * @warning this function is variable time with respect to x and y
371
            */
372
            bool mul2_vartime_x_mod_order_eq(const EC_Scalar& v,
373
                                             const EC_Scalar& c,
374
                                             const EC_Scalar& x,
375
                                             const EC_Scalar& y) const;
376
377
            ~Mul2Table();
378
            Mul2Table(const Mul2Table& other) = delete;
379
            Mul2Table(Mul2Table&& other) noexcept;
380
            Mul2Table& operator=(const Mul2Table& other) = delete;
381
            Mul2Table& operator=(Mul2Table&& other) noexcept;
382
383
         private:
384
            std::unique_ptr<EC_Mul2Table_Data> m_tbl;
385
      };
386
387
      /**
388
      * Return the OID of these domain parameters
389
      * @result the OID
390
      */
391
      const OID& get_curve_oid() const;
392
393
      /**
394
      * Return the prime modulus of the field
395
      */
396
      const BigInt& get_p() const;
397
398
      /**
399
      * Return the a parameter of the elliptic curve equation
400
      */
401
      const BigInt& get_a() const;
402
403
      /**
404
      * Return the b parameter of the elliptic curve equation
405
      */
406
      const BigInt& get_b() const;
407
408
      /**
409
      * Return the x coordinate of the base point
410
      */
411
      const BigInt& get_g_x() const;
412
413
      /**
414
      * Return the y coordinate of the base point
415
      */
416
      const BigInt& get_g_y() const;
417
418
      /**
419
      * Return the order of the base point
420
      * @result order of the base point
421
      */
422
      const BigInt& get_order() const;
423
424
      /**
425
      * Return the cofactor
426
      * @result the cofactor
427
      * TODO(Botan4): Remove this
428
      */
429
      const BigInt& get_cofactor() const;
430
431
      /**
432
      * Return true if the cofactor is > 1
433
      * TODO(Botan4): Remove this
434
      */
435
      bool has_cofactor() const;
436
437
      /*
438
      * For internal use only
439
      * TODO(Botan4): Move this to an internal header
440
      */
441
      static std::shared_ptr<EC_Group_Data> EC_group_info(const OID& oid);
442
443
      /*
444
      * For internal use only
445
      *
446
      * @warning this invalidates pointers and can cause memory corruption.
447
      * This function exists only to be called in tests.
448
      *
449
      * TODO(Botan4): Move this to an internal header
450
      */
451
      static size_t clear_registered_curve_data();
452
453
      /*
454
      * For internal use only
455
      * TODO(Botan4): Move this to an internal header
456
      */
457
      static OID EC_group_identity_from_order(const BigInt& order);
458
459
      /*
460
      * For internal use only
461
      */
462
1.10k
      const std::shared_ptr<EC_Group_Data>& _data() const { return m_data; }
463
464
#if defined(BOTAN_HAS_LEGACY_EC_POINT)
465
      /**
466
      * Check if y is a plausible point on the curve
467
      *
468
      * In particular, checks that it is a point on the curve, not infinity,
469
      * and that it has order matching the group.
470
      */
471
      bool verify_public_element(const EC_Point& y) const;
472
473
      /**
474
      * OS2ECP (Octet String To Elliptic Curve Point)
475
      *
476
      * Deserialize an encoded point. Verifies that the point is on the curve.
477
      */
478
0
      BOTAN_DEPRECATED("Use EC_AffinePoint::deserialize") EC_Point OS2ECP(const uint8_t bits[], size_t len) const {
479
0
         return EC_AffinePoint(*this, std::span{bits, len}).to_legacy_point();
480
0
      }
481
482
      BOTAN_DEPRECATED("Use EC_AffinePoint::deserialize")
483
0
      EC_Point OS2ECP(std::span<const uint8_t> encoded_point) const {
484
0
         return EC_AffinePoint(*this, encoded_point).to_legacy_point();
485
0
      }
486
487
      /**
488
      * Return group base point
489
      * @result base point
490
      */
491
      BOTAN_DEPRECATED("Use EC_AffinePoint::generator") const EC_Point& get_base_point() const;
492
493
      // Everything below here will be removed in a future release:
494
495
      /**
496
      * Return the canonical group generator
497
      * @result standard generator of the curve
498
      */
499
      BOTAN_DEPRECATED("Use EC_AffinePoint::generator") const EC_Point& generator() const;
500
501
      /**
502
      * Multi exponentiate. Not constant time.
503
      * @return base_point*x + h*y
504
      */
505
      BOTAN_DEPRECATED("Use EC_Group::Mul2Table")
506
0
      EC_Point point_multiply(const BigInt& x_bn, const EC_Point& h_pt, const BigInt& y_bn) const {
507
0
         auto x = EC_Scalar::from_bigint(*this, x_bn);
508
0
         auto y = EC_Scalar::from_bigint(*this, y_bn);
509
0
         auto h = EC_AffinePoint(*this, h_pt);
510
0
511
0
         Mul2Table gh_mul(h);
512
0
513
0
         if(auto r = gh_mul.mul2_vartime(x, y)) {
514
0
            return r->to_legacy_point();
515
0
         } else {
516
0
            return EC_AffinePoint::identity(*this).to_legacy_point();
517
0
         }
518
0
      }
519
520
      /**
521
      * Blinded point multiplication, attempts resistance to side channels
522
      * @param k_bn the scalar
523
      * @param rng a random number generator
524
      * @return base_point*k
525
      */
526
      BOTAN_DEPRECATED("Use EC_AffinePoint and EC_Scalar")
527
      EC_Point blinded_base_point_multiply(const BigInt& k_bn,
528
                                           RandomNumberGenerator& rng,
529
0
                                           std::vector<BigInt>& /*ws*/) const {
530
0
         auto k = EC_Scalar::from_bigint(*this, k_bn);
531
0
         auto pt = EC_AffinePoint::g_mul(k, rng);
532
0
         return pt.to_legacy_point();
533
0
      }
534
535
      /**
536
      * Blinded point multiplication, attempts resistance to side channels
537
      * Returns just the x coordinate of the point
538
      *
539
      * @param k_bn the scalar
540
      * @param rng a random number generator
541
      * @return x coordinate of base_point*k
542
      */
543
      BOTAN_DEPRECATED("Use EC_AffinePoint and EC_Scalar")
544
      BigInt blinded_base_point_multiply_x(const BigInt& k_bn,
545
                                           RandomNumberGenerator& rng,
546
0
                                           std::vector<BigInt>& /*ws*/) const {
547
0
         auto k = EC_Scalar::from_bigint(*this, k_bn);
548
0
         return BigInt(EC_AffinePoint::g_mul(k, rng).x_bytes());
549
0
      }
550
551
      /**
552
      * Blinded point multiplication, attempts resistance to side channels
553
      * @param point input point
554
      * @param k_bn the scalar
555
      * @param rng a random number generator
556
      * @return point*k
557
      */
558
      BOTAN_DEPRECATED("Use EC_AffinePoint and EC_Scalar")
559
      EC_Point blinded_var_point_multiply(const EC_Point& point,
560
                                          const BigInt& k_bn,
561
                                          RandomNumberGenerator& rng,
562
0
                                          std::vector<BigInt>& /*ws*/) const {
563
0
         auto k = EC_Scalar::from_bigint(*this, k_bn);
564
0
         auto pt = EC_AffinePoint(*this, point);
565
0
         return pt.mul(k, rng).to_legacy_point();
566
0
      }
567
568
      /**
569
      * Return a random scalar ie an integer in [1,order)
570
      */
571
0
      BOTAN_DEPRECATED("Use EC_Scalar::random") BigInt random_scalar(RandomNumberGenerator& rng) const {
572
0
         return EC_Scalar::random(*this, rng).to_bigint();
573
0
      }
574
575
      /**
576
      * Hash onto the curve.
577
      * For some curve types no mapping is currently available, in this
578
      * case this function will throw an exception.
579
      *
580
      * @param hash_fn the hash function to use (typically "SHA-256" or "SHA-512")
581
      * @param input the input to hash
582
      * @param input_len length of input in bytes
583
      * @param domain_sep a domain seperator
584
      * @param domain_sep_len length of domain_sep in bytes
585
      * @param random_oracle if the mapped point must be uniform (use
586
               "true" here unless you know what you are doing)
587
      */
588
      BOTAN_DEPRECATED("Use EC_AffinePoint")
589
      EC_Point hash_to_curve(std::string_view hash_fn,
590
                             const uint8_t input[],
591
                             size_t input_len,
592
                             const uint8_t domain_sep[],
593
                             size_t domain_sep_len,
594
0
                             bool random_oracle = true) const {
595
0
         auto inp = std::span{input, input_len};
596
0
         auto dst = std::span{domain_sep, domain_sep_len};
597
0
598
0
         if(random_oracle) {
599
0
            return EC_AffinePoint::hash_to_curve_ro(*this, hash_fn, inp, dst).to_legacy_point();
600
0
         } else {
601
0
            return EC_AffinePoint::hash_to_curve_nu(*this, hash_fn, inp, dst).to_legacy_point();
602
0
         }
603
0
      }
604
605
      /**
606
      * Hash onto the curve.
607
      * For some curve types no mapping is currently available, in this
608
      * case this function will throw an exception.
609
      *
610
      * @param hash_fn the hash function to use (typically "SHA-256" or "SHA-512")
611
      * @param input the input to hash
612
      * @param input_len length of input in bytes
613
      * @param domain_sep a domain seperator
614
      * @param random_oracle if the mapped point must be uniform (use
615
               "true" here unless you know what you are doing)
616
      */
617
      BOTAN_DEPRECATED("Use EC_AffinePoint")
618
      EC_Point hash_to_curve(std::string_view hash_fn,
619
                             const uint8_t input[],
620
                             size_t input_len,
621
                             std::string_view domain_sep,
622
0
                             bool random_oracle = true) const {
623
0
         auto inp = std::span{input, input_len};
624
0
625
0
         if(random_oracle) {
626
0
            return EC_AffinePoint::hash_to_curve_ro(*this, hash_fn, inp, domain_sep).to_legacy_point();
627
0
         } else {
628
0
            return EC_AffinePoint::hash_to_curve_nu(*this, hash_fn, inp, domain_sep).to_legacy_point();
629
0
         }
630
0
      }
631
632
      /**
633
      * Return a point on this curve with the affine values x, y
634
      */
635
0
      BOTAN_DEPRECATED("Deprecated - use EC_AffinePoint") EC_Point point(const BigInt& x, const BigInt& y) const {
636
0
         if(auto pt = EC_AffinePoint::from_bigint_xy(*this, x, y)) {
637
0
            return pt->to_legacy_point();
638
0
         } else {
639
0
            throw Decoding_Error("Invalid x/y coordinates for elliptic curve point");
640
0
         }
641
0
      }
642
643
      /**
644
      * Return the zero (or infinite) point on this curve
645
      */
646
0
      BOTAN_DEPRECATED("Deprecated no replacement") EC_Point zero_point() const {
647
0
         return EC_AffinePoint::identity(*this).to_legacy_point();
648
0
      }
649
#endif
650
651
      /**
652
      * Return if a == -3 mod p
653
      */
654
0
      BOTAN_DEPRECATED("Deprecated no replacement") bool a_is_minus_3() const { return get_a() + 3 == get_p(); }
655
656
      /**
657
      * Return if a == 0 mod p
658
      */
659
0
      BOTAN_DEPRECATED("Deprecated no replacement") bool a_is_zero() const { return get_a().is_zero(); }
660
661
      /*
662
      * Reduce x modulo the order
663
      */
664
0
      BOTAN_DEPRECATED("Use EC_Scalar") BigInt mod_order(const BigInt& x) const {
665
0
         return EC_Scalar::from_bytes_mod_order(*this, x.serialize()).to_bigint();
666
0
      }
667
668
      /*
669
      * Return inverse of x modulo the order
670
      */
671
0
      BOTAN_DEPRECATED("Use EC_Scalar") BigInt inverse_mod_order(const BigInt& x) const {
672
0
         return EC_Scalar::from_bigint(*this, x).invert().to_bigint();
673
0
      }
674
675
      /*
676
      * Reduce (x*x) modulo the order
677
      */
678
0
      BOTAN_DEPRECATED("Use EC_Scalar") BigInt square_mod_order(const BigInt& x) const {
679
0
         auto xs = EC_Scalar::from_bigint(*this, x);
680
0
         xs.square_self();
681
0
         return xs.to_bigint();
682
0
      }
683
684
      /*
685
      * Reduce (x*y) modulo the order
686
      */
687
0
      BOTAN_DEPRECATED("Use EC_Scalar") BigInt multiply_mod_order(const BigInt& x, const BigInt& y) const {
688
0
         auto xs = EC_Scalar::from_bigint(*this, x);
689
0
         auto ys = EC_Scalar::from_bigint(*this, y);
690
0
         return (xs * ys).to_bigint();
691
0
      }
692
693
      /*
694
      * Reduce (x*y*z) modulo the order
695
      */
696
      BOTAN_DEPRECATED("Use EC_Scalar")
697
0
      BigInt multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const {
698
0
         auto xs = EC_Scalar::from_bigint(*this, x);
699
0
         auto ys = EC_Scalar::from_bigint(*this, y);
700
0
         auto zs = EC_Scalar::from_bigint(*this, z);
701
0
         return (xs * ys * zs).to_bigint();
702
0
      }
703
704
      /*
705
      * Return x^3 modulo the order
706
      */
707
0
      BOTAN_DEPRECATED("Deprecated no replacement") BigInt cube_mod_order(const BigInt& x) const {
708
0
         auto xs = EC_Scalar::from_bigint(*this, x);
709
0
         return (xs * xs * xs).to_bigint();
710
0
      }
711
712
0
      BOTAN_DEPRECATED("Just serialize the point and check") size_t point_size(EC_Point_Format format) const {
713
0
         // Hybrid and standard format are (x,y), compressed is y, +1 format byte
714
0
         if(format == EC_Point_Format::Compressed) {
715
0
            return (1 + get_p_bytes());
716
0
         } else {
717
0
            return (1 + 2 * get_p_bytes());
718
0
         }
719
0
      }
720
721
   private:
722
      static EC_Group_Data_Map& ec_group_data();
723
724
      explicit EC_Group(std::shared_ptr<EC_Group_Data>&& data);
725
726
      static std::pair<std::shared_ptr<EC_Group_Data>, bool> BER_decode_EC_group(std::span<const uint8_t> ber,
727
                                                                                 EC_Group_Source source);
728
729
      static std::shared_ptr<EC_Group_Data> load_EC_group_info(const char* p,
730
                                                               const char* a,
731
                                                               const char* b,
732
                                                               const char* g_x,
733
                                                               const char* g_y,
734
                                                               const char* order,
735
                                                               const OID& oid);
736
737
      const EC_Group_Data& data() const;
738
739
      // Member data
740
      std::shared_ptr<EC_Group_Data> m_data;
741
      bool m_explicit_encoding = false;
742
};
743
744
0
inline bool operator!=(const EC_Group& lhs, const EC_Group& rhs) {
745
0
   return !(lhs == rhs);
746
0
}
747
748
}  // namespace Botan
749
750
#endif