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