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