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