Botan  2.18.2
Crypto and TLS for C++11
ec_group.cpp
Go to the documentation of this file.
1 /*
2 * ECC Domain Parameters
3 *
4 * (C) 2007 Falko Strenzke, FlexSecure GmbH
5 * (C) 2008,2018 Jack Lloyd
6 * (C) 2018 Tobias Niemann
7 *
8 * Botan is released under the Simplified BSD License (see license.txt)
9 */
10 
11 #include <botan/ec_group.h>
12 #include <botan/internal/point_mul.h>
13 #include <botan/internal/primality.h>
14 #include <botan/ber_dec.h>
15 #include <botan/der_enc.h>
16 #include <botan/pem.h>
17 #include <botan/reducer.h>
18 #include <botan/mutex.h>
19 #include <botan/rng.h>
20 #include <vector>
21 
22 namespace Botan {
23 
24 class EC_Group_Data final
25  {
26  public:
27 
28  EC_Group_Data(const BigInt& p,
29  const BigInt& a,
30  const BigInt& b,
31  const BigInt& g_x,
32  const BigInt& g_y,
33  const BigInt& order,
34  const BigInt& cofactor,
35  const OID& oid,
36  EC_Group_Source source) :
37  m_curve(p, a, b),
38  m_base_point(m_curve, g_x, g_y),
39  m_g_x(g_x),
40  m_g_y(g_y),
41  m_order(order),
42  m_cofactor(cofactor),
43  m_mod_order(order),
44  m_base_mult(m_base_point, m_mod_order),
45  m_oid(oid),
46  m_p_bits(p.bits()),
47  m_order_bits(order.bits()),
48  m_a_is_minus_3(a == p - 3),
49  m_a_is_zero(a.is_zero()),
50  m_source(source)
51  {
52  }
53 
54  bool match(const BigInt& p, const BigInt& a, const BigInt& b,
55  const BigInt& g_x, const BigInt& g_y,
56  const BigInt& order, const BigInt& cofactor) const
57  {
58  return (this->p() == p &&
59  this->a() == a &&
60  this->b() == b &&
61  this->order() == order &&
62  this->cofactor() == cofactor &&
63  this->g_x() == g_x &&
64  this->g_y() == g_y);
65  }
66 
67  void set_oid(const OID& oid)
68  {
69  BOTAN_STATE_CHECK(m_oid.empty());
70  m_oid = oid;
71  }
72 
73  const OID& oid() const { return m_oid; }
74  const BigInt& p() const { return m_curve.get_p(); }
75  const BigInt& a() const { return m_curve.get_a(); }
76  const BigInt& b() const { return m_curve.get_b(); }
77  const BigInt& order() const { return m_order; }
78  const BigInt& cofactor() const { return m_cofactor; }
79  const BigInt& g_x() const { return m_g_x; }
80  const BigInt& g_y() const { return m_g_y; }
81 
82  size_t p_bits() const { return m_p_bits; }
83  size_t p_bytes() const { return (m_p_bits + 7) / 8; }
84 
85  size_t order_bits() const { return m_order_bits; }
86  size_t order_bytes() const { return (m_order_bits + 7) / 8; }
87 
88  const CurveGFp& curve() const { return m_curve; }
89  const PointGFp& base_point() const { return m_base_point; }
90 
91  bool a_is_minus_3() const { return m_a_is_minus_3; }
92  bool a_is_zero() const { return m_a_is_zero; }
93 
94  BigInt mod_order(const BigInt& x) const { return m_mod_order.reduce(x); }
95 
96  BigInt square_mod_order(const BigInt& x) const
97  {
98  return m_mod_order.square(x);
99  }
100 
101  BigInt multiply_mod_order(const BigInt& x, const BigInt& y) const
102  {
103  return m_mod_order.multiply(x, y);
104  }
105 
106  BigInt multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const
107  {
108  return m_mod_order.multiply(m_mod_order.multiply(x, y), z);
109  }
110 
111  BigInt inverse_mod_order(const BigInt& x) const
112  {
113  return inverse_mod(x, m_order);
114  }
115 
116  PointGFp blinded_base_point_multiply(const BigInt& k,
117  RandomNumberGenerator& rng,
118  std::vector<BigInt>& ws) const
119  {
120  return m_base_mult.mul(k, rng, m_order, ws);
121  }
122 
123  EC_Group_Source source() const { return m_source; }
124 
125  private:
126  CurveGFp m_curve;
127  PointGFp m_base_point;
128 
129  BigInt m_g_x;
130  BigInt m_g_y;
131  BigInt m_order;
132  BigInt m_cofactor;
133  Modular_Reducer m_mod_order;
134  PointGFp_Base_Point_Precompute m_base_mult;
135  OID m_oid;
136  size_t m_p_bits;
137  size_t m_order_bits;
138  bool m_a_is_minus_3;
139  bool m_a_is_zero;
140  EC_Group_Source m_source;
141  };
142 
143 class EC_Group_Data_Map final
144  {
145  public:
146  EC_Group_Data_Map() {}
147 
148  size_t clear()
149  {
150  lock_guard_type<mutex_type> lock(m_mutex);
151  size_t count = m_registered_curves.size();
152  m_registered_curves.clear();
153  return count;
154  }
155 
156  std::shared_ptr<EC_Group_Data> lookup(const OID& oid)
157  {
158  lock_guard_type<mutex_type> lock(m_mutex);
159 
160  for(auto i : m_registered_curves)
161  {
162  if(i->oid() == oid)
163  return i;
164  }
165 
166  // Not found, check hardcoded data
167  std::shared_ptr<EC_Group_Data> data = EC_Group::EC_group_info(oid);
168 
169  if(data)
170  {
171  m_registered_curves.push_back(data);
172  return data;
173  }
174 
175  // Nope, unknown curve
176  return std::shared_ptr<EC_Group_Data>();
177  }
178 
179  std::shared_ptr<EC_Group_Data> lookup_or_create(const BigInt& p,
180  const BigInt& a,
181  const BigInt& b,
182  const BigInt& g_x,
183  const BigInt& g_y,
184  const BigInt& order,
185  const BigInt& cofactor,
186  const OID& oid,
187  EC_Group_Source source)
188  {
189  lock_guard_type<mutex_type> lock(m_mutex);
190 
191  for(auto i : m_registered_curves)
192  {
193  if(!oid.empty())
194  {
195  if(i->oid() == oid)
196  {
197  if(!i->match(p, a, b, g_x, g_y, order, cofactor))
198  throw Invalid_Argument("Attempting to register a curve using OID " + oid.to_string() +
199  " but another curve is already registered using that OID");
200  return i;
201  }
202  else if(i->oid().has_value())
203  continue; // distinct OIDs so not a match
204  }
205 
206  if(i->match(p, a, b, g_x, g_y, order, cofactor))
207  {
208  /*
209  * If the same curve was previously created without an OID
210  * but has been registered again using an OID, save that OID.
211  */
212  if(oid.empty() == false)
213  {
214  if(i->oid().empty() == true)
215  {
216  i->set_oid(oid);
217  }
218  else
219  {
220  throw Invalid_Argument("Cannot register ECC group with OID " + oid.to_string() +
221  " already registered using " + i->oid().to_string());
222  }
223  }
224  return i;
225  }
226  }
227 
228  // Not found - if OID is set try looking up that way
229 
230  if(oid.has_value())
231  {
232  // Not located in existing store - try hardcoded data set
233  std::shared_ptr<EC_Group_Data> data = EC_Group::EC_group_info(oid);
234 
235  if(data)
236  {
237  m_registered_curves.push_back(data);
238  return data;
239  }
240  }
241 
242  // Not found or no OID, add data and return
243  std::shared_ptr<EC_Group_Data> d =
244  std::make_shared<EC_Group_Data>(p, a, b, g_x, g_y, order, cofactor, oid, source);
245 
246  m_registered_curves.push_back(d);
247  return d;
248  }
249 
250  private:
251  mutex_type m_mutex;
252  std::vector<std::shared_ptr<EC_Group_Data>> m_registered_curves;
253  };
254 
255 //static
256 EC_Group_Data_Map& EC_Group::ec_group_data()
257  {
258  /*
259  * This exists purely to ensure the allocator is constructed before g_ec_data,
260  * which ensures that its destructor runs after ~g_ec_data is complete.
261  */
262 
263  static Allocator_Initializer g_init_allocator;
264  static EC_Group_Data_Map g_ec_data;
265  return g_ec_data;
266  }
267 
268 //static
270  {
271  return ec_group_data().clear();
272  }
273 
274 //static
275 std::shared_ptr<EC_Group_Data>
276 EC_Group::load_EC_group_info(const char* p_str,
277  const char* a_str,
278  const char* b_str,
279  const char* g_x_str,
280  const char* g_y_str,
281  const char* order_str,
282  const OID& oid)
283  {
284  const BigInt p(p_str);
285  const BigInt a(a_str);
286  const BigInt b(b_str);
287  const BigInt g_x(g_x_str);
288  const BigInt g_y(g_y_str);
289  const BigInt order(order_str);
290  const BigInt cofactor(1); // implicit
291 
292  return std::make_shared<EC_Group_Data>(p, a, b, g_x, g_y, order, cofactor, oid, EC_Group_Source::Builtin);
293  }
294 
295 //static
296 std::shared_ptr<EC_Group_Data> EC_Group::BER_decode_EC_group(const uint8_t bits[], size_t len,
297  EC_Group_Source source)
298  {
299  BER_Decoder ber(bits, len);
300  BER_Object obj = ber.get_next_object();
301 
302  if(obj.type() == NULL_TAG)
303  {
304  throw Decoding_Error("Cannot handle ImplicitCA ECC parameters");
305  }
306  else if(obj.type() == OBJECT_ID)
307  {
308  OID dom_par_oid;
309  BER_Decoder(bits, len).decode(dom_par_oid);
310  return ec_group_data().lookup(dom_par_oid);
311  }
312  else if(obj.type() == SEQUENCE)
313  {
314  BigInt p, a, b, order, cofactor;
315  std::vector<uint8_t> base_pt;
316  std::vector<uint8_t> seed;
317 
318  BER_Decoder(bits, len)
319  .start_cons(SEQUENCE)
320  .decode_and_check<size_t>(1, "Unknown ECC param version code")
321  .start_cons(SEQUENCE)
322  .decode_and_check(OID("1.2.840.10045.1.1"),
323  "Only prime ECC fields supported")
324  .decode(p)
325  .end_cons()
326  .start_cons(SEQUENCE)
327  .decode_octet_string_bigint(a)
328  .decode_octet_string_bigint(b)
329  .decode_optional_string(seed, BIT_STRING, BIT_STRING)
330  .end_cons()
331  .decode(base_pt, OCTET_STRING)
332  .decode(order)
333  .decode(cofactor)
334  .end_cons()
335  .verify_end();
336 
337  if(p.bits() < 64 || p.is_negative() || !is_bailie_psw_probable_prime(p))
338  throw Decoding_Error("Invalid ECC p parameter");
339 
340  if(a.is_negative() || a >= p)
341  throw Decoding_Error("Invalid ECC a parameter");
342 
343  if(b <= 0 || b >= p)
344  throw Decoding_Error("Invalid ECC b parameter");
345 
346  if(order <= 0 || !is_bailie_psw_probable_prime(order))
347  throw Decoding_Error("Invalid ECC order parameter");
348 
349  if(cofactor <= 0 || cofactor >= 16)
350  throw Decoding_Error("Invalid ECC cofactor parameter");
351 
352  std::pair<BigInt, BigInt> base_xy = Botan::OS2ECP(base_pt.data(), base_pt.size(), p, a, b);
353 
354  return ec_group_data().lookup_or_create(p, a, b, base_xy.first, base_xy.second,
355  order, cofactor, OID(), source);
356  }
357  else
358  {
359  throw Decoding_Error("Unexpected tag while decoding ECC domain params");
360  }
361  }
362 
364  {
365  }
366 
368  {
369  // shared_ptr possibly freed here
370  }
371 
372 EC_Group::EC_Group(const OID& domain_oid)
373  {
374  this->m_data = ec_group_data().lookup(domain_oid);
375  if(!this->m_data)
376  throw Invalid_Argument("Unknown EC_Group " + domain_oid.to_string());
377  }
378 
379 EC_Group::EC_Group(const std::string& str)
380  {
381  if(str == "")
382  return; // no initialization / uninitialized
383 
384  try
385  {
386  const OID oid = OID::from_string(str);
387  if(oid.has_value())
388  m_data = ec_group_data().lookup(oid);
389  }
390  catch(...)
391  {
392  }
393 
394  if(m_data == nullptr)
395  {
396  if(str.size() > 30 && str.substr(0, 29) == "-----BEGIN EC PARAMETERS-----")
397  {
398  // OK try it as PEM ...
399  secure_vector<uint8_t> ber = PEM_Code::decode_check_label(str, "EC PARAMETERS");
400  this->m_data = BER_decode_EC_group(ber.data(), ber.size(), EC_Group_Source::ExternalSource);
401  }
402  }
403 
404  if(m_data == nullptr)
405  throw Invalid_Argument("Unknown ECC group '" + str + "'");
406  }
407 
408 //static
409 EC_Group EC_Group::EC_Group_from_PEM(const std::string& pem)
410  {
411  const auto ber = PEM_Code::decode_check_label(pem, "EC PARAMETERS");
412  return EC_Group(ber.data(), ber.size());
413  }
414 
415 //static
416 std::string EC_Group::PEM_for_named_group(const std::string& name)
417  {
418  try
419  {
420  EC_Group group(name);
421  return group.PEM_encode();
422  }
423  catch(...)
424  {
425  return "";
426  }
427  }
428 
430  const BigInt& a,
431  const BigInt& b,
432  const BigInt& base_x,
433  const BigInt& base_y,
434  const BigInt& order,
435  const BigInt& cofactor,
436  const OID& oid)
437  {
438  m_data = ec_group_data().lookup_or_create(p, a, b, base_x, base_y, order, cofactor, oid,
440  }
441 
442 EC_Group::EC_Group(const uint8_t ber[], size_t ber_len)
443  {
444  m_data = BER_decode_EC_group(ber, ber_len, EC_Group_Source::ExternalSource);
445  }
446 
447 const EC_Group_Data& EC_Group::data() const
448  {
449  if(m_data == nullptr)
450  throw Invalid_State("EC_Group uninitialized");
451  return *m_data;
452  }
453 
455  {
456  return data().curve();
457  }
458 
460  {
461  return data().a_is_minus_3();
462  }
463 
465  {
466  return data().a_is_zero();
467  }
468 
469 size_t EC_Group::get_p_bits() const
470  {
471  return data().p_bits();
472  }
473 
474 size_t EC_Group::get_p_bytes() const
475  {
476  return data().p_bytes();
477  }
478 
480  {
481  return data().order_bits();
482  }
483 
485  {
486  return data().order_bytes();
487  }
488 
489 const BigInt& EC_Group::get_p() const
490  {
491  return data().p();
492  }
493 
494 const BigInt& EC_Group::get_a() const
495  {
496  return data().a();
497  }
498 
499 const BigInt& EC_Group::get_b() const
500  {
501  return data().b();
502  }
503 
505  {
506  return data().base_point();
507  }
508 
510  {
511  return data().order();
512  }
513 
514 const BigInt& EC_Group::get_g_x() const
515  {
516  return data().g_x();
517  }
518 
519 const BigInt& EC_Group::get_g_y() const
520  {
521  return data().g_y();
522  }
523 
525  {
526  return data().cofactor();
527  }
528 
530  {
531  return data().mod_order(k);
532  }
533 
535  {
536  return data().square_mod_order(x);
537  }
538 
540  {
541  return data().multiply_mod_order(x, y);
542  }
543 
544 BigInt EC_Group::multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const
545  {
546  return data().multiply_mod_order(x, y, z);
547  }
548 
550  {
551  return data().inverse_mod_order(x);
552  }
553 
555  {
556  return data().oid();
557  }
558 
560  {
561  return data().source();
562  }
563 
565  {
566  // Hybrid and standard format are (x,y), compressed is y, +1 format byte
567  if(format == PointGFp::COMPRESSED)
568  return (1 + get_p_bytes());
569  else
570  return (1 + 2*get_p_bytes());
571  }
572 
573 PointGFp EC_Group::OS2ECP(const uint8_t bits[], size_t len) const
574  {
575  return Botan::OS2ECP(bits, len, data().curve());
576  }
577 
578 PointGFp EC_Group::point(const BigInt& x, const BigInt& y) const
579  {
580  // TODO: randomize the representation?
581  return PointGFp(data().curve(), x, y);
582  }
583 
584 PointGFp EC_Group::point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const
585  {
587  return xy_mul.multi_exp(x, y);
588  }
589 
592  std::vector<BigInt>& ws) const
593  {
594  return data().blinded_base_point_multiply(k, rng, ws);
595  }
596 
599  std::vector<BigInt>& ws) const
600  {
601  const PointGFp pt = data().blinded_base_point_multiply(k, rng, ws);
602 
603  if(pt.is_zero())
604  return 0;
605  return pt.get_affine_x();
606  }
607 
609  {
610  return BigInt::random_integer(rng, 1, get_order());
611  }
612 
614  const BigInt& k,
616  std::vector<BigInt>& ws) const
617  {
618  PointGFp_Var_Point_Precompute mul(point, rng, ws);
619  return mul.mul(k, rng, get_order(), ws);
620  }
621 
623  {
624  return PointGFp(data().curve());
625  }
626 
627 std::vector<uint8_t>
629  {
630  std::vector<uint8_t> output;
631 
632  DER_Encoder der(output);
633 
634  if(form == EC_DOMPAR_ENC_EXPLICIT)
635  {
636  const size_t ecpVers1 = 1;
637  const OID curve_type("1.2.840.10045.1.1"); // prime field
638 
639  const size_t p_bytes = get_p_bytes();
640 
641  der.start_cons(SEQUENCE)
642  .encode(ecpVers1)
644  .encode(curve_type)
645  .encode(get_p())
646  .end_cons()
648  .encode(BigInt::encode_1363(get_a(), p_bytes),
649  OCTET_STRING)
650  .encode(BigInt::encode_1363(get_b(), p_bytes),
651  OCTET_STRING)
652  .end_cons()
654  .encode(get_order())
655  .encode(get_cofactor())
656  .end_cons();
657  }
658  else if(form == EC_DOMPAR_ENC_OID)
659  {
660  const OID oid = get_curve_oid();
661  if(oid.empty())
662  {
663  throw Encoding_Error("Cannot encode EC_Group as OID because OID not set");
664  }
665  der.encode(oid);
666  }
667  else if(form == EC_DOMPAR_ENC_IMPLICITCA)
668  {
669  der.encode_null();
670  }
671  else
672  {
673  throw Internal_Error("EC_Group::DER_encode: Unknown encoding");
674  }
675 
676  return output;
677  }
678 
679 std::string EC_Group::PEM_encode() const
680  {
681  const std::vector<uint8_t> der = DER_encode(EC_DOMPAR_ENC_EXPLICIT);
682  return PEM_Code::encode(der, "EC PARAMETERS");
683  }
684 
685 bool EC_Group::operator==(const EC_Group& other) const
686  {
687  if(m_data == other.m_data)
688  return true; // same shared rep
689 
690  /*
691  * No point comparing order/cofactor as they are uniquely determined
692  * by the curve equation (p,a,b) and the base point.
693  */
694  return (get_p() == other.get_p() &&
695  get_a() == other.get_a() &&
696  get_b() == other.get_b() &&
697  get_g_x() == other.get_g_x() &&
698  get_g_y() == other.get_g_y());
699  }
700 
702  {
703  //check that public point is not at infinity
704  if(point.is_zero())
705  return false;
706 
707  //check that public point is on the curve
708  if(point.on_the_curve() == false)
709  return false;
710 
711  //check that public point has order q
712  if((point * get_order()).is_zero() == false)
713  return false;
714 
715  if(get_cofactor() > 1)
716  {
717  if((point * get_cofactor()).is_zero())
718  return false;
719  }
720 
721  return true;
722  }
723 
725  bool strong) const
726  {
727  const bool is_builtin = source() == EC_Group_Source::Builtin;
728 
729  if(is_builtin && !strong)
730  return true;
731 
732  const BigInt& p = get_p();
733  const BigInt& a = get_a();
734  const BigInt& b = get_b();
735  const BigInt& order = get_order();
736  const PointGFp& base_point = get_base_point();
737 
738  if(p <= 3 || order <= 0)
739  return false;
740  if(a < 0 || a >= p)
741  return false;
742  if(b <= 0 || b >= p)
743  return false;
744 
745  const size_t test_prob = 128;
746  const bool is_randomly_generated = is_builtin;
747 
748  //check if field modulus is prime
749  if(!is_prime(p, rng, test_prob, is_randomly_generated))
750  {
751  return false;
752  }
753 
754  //check if order is prime
755  if(!is_prime(order, rng, test_prob, is_randomly_generated))
756  {
757  return false;
758  }
759 
760  //compute the discriminant: 4*a^3 + 27*b^2 which must be nonzero
761  const Modular_Reducer mod_p(p);
762 
763  const BigInt discriminant = mod_p.reduce(
764  mod_p.multiply(4, mod_p.cube(a)) +
765  mod_p.multiply(27, mod_p.square(b)));
766 
767  if(discriminant == 0)
768  {
769  return false;
770  }
771 
772  //check for valid cofactor
773  if(get_cofactor() < 1)
774  {
775  return false;
776  }
777 
778  //check if the base point is on the curve
779  if(!base_point.on_the_curve())
780  {
781  return false;
782  }
783  if((base_point * get_cofactor()).is_zero())
784  {
785  return false;
786  }
787  //check if order of the base point is correct
788  if(!(base_point * order).is_zero())
789  {
790  return false;
791  }
792 
793  return true;
794  }
795 
796 }
BigInt cube(const BigInt &x) const
Definition: reducer.h:47
static EC_Group EC_Group_from_PEM(const std::string &pem)
Definition: ec_group.cpp:409
size_t get_p_bytes() const
Definition: ec_group.cpp:474
const OID & get_curve_oid() const
Definition: ec_group.cpp:554
PointGFp point(const BigInt &x, const BigInt &y) const
Definition: ec_group.cpp:578
PointGFp multi_exp(const BigInt &k1, const BigInt &k2) const
Definition: point_mul.cpp:394
size_t get_p_bits() const
Definition: ec_group.cpp:469
BigInt multiply_mod_order(const BigInt &x, const BigInt &y) const
Definition: ec_group.cpp:539
BigInt mod_order(const BigInt &x) const
Definition: ec_group.cpp:529
const BigInt & get_order() const
Definition: ec_group.cpp:509
bool a_is_zero() const
Definition: ec_group.cpp:464
noop_mutex mutex_type
Definition: mutex.h:52
int(* final)(unsigned char *, CTX *)
BigInt blinded_base_point_multiply_x(const BigInt &k, RandomNumberGenerator &rng, std::vector< BigInt > &ws) const
Definition: ec_group.cpp:597
#define BOTAN_STATE_CHECK(expr)
Definition: assert.h:49
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
Definition: numthry.cpp:228
const CurveGFp & get_curve() const
Definition: ec_group.cpp:454
static BigInt random_integer(RandomNumberGenerator &rng, const BigInt &min, const BigInt &max)
Definition: big_rand.cpp:45
DER_Encoder & end_cons()
Definition: der_enc.cpp:191
size_t point_size(PointGFp::Compression_Type format) const
Definition: ec_group.cpp:564
BigInt get_affine_x() const
Definition: point_gfp.cpp:505
static std::string PEM_for_named_group(const std::string &name)
Definition: ec_group.cpp:416
PointGFp point_multiply(const BigInt &x, const PointGFp &pt, const BigInt &y) const
Definition: ec_group.cpp:584
bool a_is_minus_3() const
Definition: ec_group.cpp:459
std::string to_string() const
Definition: asn1_oid.cpp:98
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:285
secure_vector< uint8_t > decode_check_label(DataSource &source, const std::string &label_want)
Definition: pem.cpp:54
bool is_bailie_psw_probable_prime(const BigInt &n, const Modular_Reducer &mod_n)
Definition: primality.cpp:92
bool verify_public_element(const PointGFp &y) const
Definition: ec_group.cpp:701
std::string name
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
BigInt random_scalar(RandomNumberGenerator &rng) const
Definition: ec_group.cpp:608
std::string PEM_encode() const
Definition: ec_group.cpp:679
const PointGFp & get_base_point() const
Definition: ec_group.cpp:504
size_t get_order_bits() const
Definition: ec_group.cpp:479
bool empty() const
Definition: asn1_obj.h:232
const BigInt & get_cofactor() const
Definition: ec_group.cpp:524
DER_Encoder & encode_null()
Definition: der_enc.cpp:277
PointGFp OS2ECP(const uint8_t bits[], size_t len) const
Definition: ec_group.cpp:573
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition: mod_inv.cpp:250
EC_Group_Source source() const
Definition: ec_group.cpp:559
Definition: alg_id.cpp:13
const BigInt & get_b() const
Definition: ec_group.cpp:499
BigInt square_mod_order(const BigInt &x) const
Definition: ec_group.cpp:534
const BigInt & get_g_x() const
Definition: ec_group.cpp:514
bool on_the_curve() const
Definition: point_gfp.cpp:544
const BigInt & get_a() const
Definition: ec_group.cpp:494
const BigInt & get_g_y() const
Definition: ec_group.cpp:519
EC_Group_Encoding
Definition: ec_group.h:23
const BigInt & get_p() const
Definition: ec_group.cpp:489
static std::shared_ptr< EC_Group_Data > EC_group_info(const OID &oid)
Definition: ec_named.cpp:13
BigInt reduce(const BigInt &x) const
Definition: reducer.cpp:37
PointGFp blinded_var_point_multiply(const PointGFp &point, const BigInt &k, RandomNumberGenerator &rng, std::vector< BigInt > &ws) const
Definition: ec_group.cpp:613
size_t get_order_bytes() const
Definition: ec_group.cpp:484
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:181
bool is_zero() const
Definition: point_gfp.h:184
bool has_value() const
Definition: asn1_obj.h:238
EC_Group_Source
Definition: ec_group.h:29
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:111
PointGFp mul(const BigInt &k, RandomNumberGenerator &rng, const BigInt &group_order, std::vector< BigInt > &ws) const
Definition: point_mul.cpp:267
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65
std::string lookup(const OID &oid)
Definition: oids.h:71
bool operator==(const EC_Group &other) const
Definition: ec_group.cpp:685
BigInt square(const BigInt &x) const
Definition: reducer.h:39
bool verify_group(RandomNumberGenerator &rng, bool strong=false) const
Definition: ec_group.cpp:724
BigInt multiply(const BigInt &x, const BigInt &y) const
Definition: reducer.h:31
PointGFp zero_point() const
Definition: ec_group.cpp:622
std::vector< uint8_t > DER_encode(EC_Group_Encoding form) const
Definition: ec_group.cpp:628
PointGFp OS2ECP(const uint8_t data[], size_t data_len, const CurveGFp &curve)
Definition: point_gfp.cpp:667
PointGFp blinded_base_point_multiply(const BigInt &k, RandomNumberGenerator &rng, std::vector< BigInt > &ws) const
Definition: ec_group.cpp:590
static size_t clear_registered_curve_data()
Definition: ec_group.cpp:269
BigInt inverse_mod_order(const BigInt &x) const
Definition: ec_group.cpp:549
static OID from_string(const std::string &str)
Definition: asn1_oid.cpp:62