Coverage Report

Created: 2025-04-11 06:45

/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