Botan  2.7.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/ber_dec.h>
14 #include <botan/der_enc.h>
15 #include <botan/oids.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 #if defined(BOTAN_HAS_SYSTEM_RNG)
23  #include <botan/system_rng.h>
24 #elif defined(BOTAN_HAS_HMAC_DRBG) && defined(BOTAN_HAS_SHA2_32)
25  #include <botan/hmac_drbg.h>
26 #endif
27 
28 namespace Botan {
29 
30 class EC_Group_Data final
31  {
32  public:
33 
34  EC_Group_Data(const BigInt& p,
35  const BigInt& a,
36  const BigInt& b,
37  const BigInt& g_x,
38  const BigInt& g_y,
39  const BigInt& order,
40  const BigInt& cofactor,
41  const OID& oid) :
42  m_curve(p, a, b),
43  m_base_point(m_curve, g_x, g_y),
44  m_g_x(g_x),
45  m_g_y(g_y),
46  m_order(order),
47  m_cofactor(cofactor),
48  m_mod_order(order),
49  m_base_mult(m_base_point, m_mod_order),
50  m_oid(oid),
51  m_p_bits(p.bits()),
52  m_order_bits(order.bits()),
53  m_a_is_minus_3(a == p - 3),
54  m_a_is_zero(a.is_zero())
55  {
56  }
57 
58  bool match(const BigInt& p, const BigInt& a, const BigInt& b,
59  const BigInt& g_x, const BigInt& g_y,
60  const BigInt& order, const BigInt& cofactor) const
61  {
62  return (this->p() == p &&
63  this->a() == a &&
64  this->b() == b &&
65  this->order() == order &&
66  this->cofactor() == cofactor &&
67  this->g_x() == g_x &&
68  this->g_y() == g_y);
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.has_value())
188  {
189  if(i->oid() == oid)
190  return i;
191  else if(i->oid().has_value())
192  continue;
193  }
194 
195  if(i->match(p, a, b, g_x, g_y, order, cofactor))
196  return i;
197  }
198 
199  // Not found - if OID is set try looking up that way
200 
201  if(oid.has_value())
202  {
203  // Not located in existing store - try hardcoded data set
204  std::shared_ptr<EC_Group_Data> data = EC_Group::EC_group_info(oid);
205 
206  if(data)
207  {
208  m_registered_curves.push_back(data);
209  return data;
210  }
211  }
212 
213  // Not found or no OID, add data and return
214  return add_curve(p, a, b, g_x, g_y, order, cofactor, oid);
215  }
216 
217  private:
218 
219  std::shared_ptr<EC_Group_Data> add_curve(const BigInt& p,
220  const BigInt& a,
221  const BigInt& b,
222  const BigInt& g_x,
223  const BigInt& g_y,
224  const BigInt& order,
225  const BigInt& cofactor,
226  const OID& oid)
227  {
228  std::shared_ptr<EC_Group_Data> d =
229  std::make_shared<EC_Group_Data>(p, a, b, g_x, g_y, order, cofactor, oid);
230 
231  // This function is always called with the lock held
232  m_registered_curves.push_back(d);
233  return d;
234  }
235 
236  mutex_type m_mutex;
237  std::vector<std::shared_ptr<EC_Group_Data>> m_registered_curves;
238  };
239 
240 //static
241 EC_Group_Data_Map& EC_Group::ec_group_data()
242  {
243  /*
244  * This exists purely to ensure the allocator is constructed before g_ec_data,
245  * which ensures that its destructor runs after ~g_ec_data is complete.
246  */
247 
248  static Allocator_Initializer g_init_allocator;
249  static EC_Group_Data_Map g_ec_data;
250  return g_ec_data;
251  }
252 
253 //static
255  {
256  return ec_group_data().clear();
257  }
258 
259 //static
260 std::shared_ptr<EC_Group_Data>
261 EC_Group::load_EC_group_info(const char* p_str,
262  const char* a_str,
263  const char* b_str,
264  const char* g_x_str,
265  const char* g_y_str,
266  const char* order_str,
267  const OID& oid)
268  {
269  const BigInt p(p_str);
270  const BigInt a(a_str);
271  const BigInt b(b_str);
272  const BigInt g_x(g_x_str);
273  const BigInt g_y(g_y_str);
274  const BigInt order(order_str);
275  const BigInt cofactor(1); // implicit
276 
277  return std::make_shared<EC_Group_Data>(p, a, b, g_x, g_y, order, cofactor, oid);
278  }
279 
280 //static
281 std::shared_ptr<EC_Group_Data> EC_Group::BER_decode_EC_group(const uint8_t bits[], size_t len)
282  {
283  BER_Decoder ber(bits, len);
284  BER_Object obj = ber.get_next_object();
285 
286  if(obj.type() == NULL_TAG)
287  {
288  throw Decoding_Error("Cannot handle ImplicitCA ECC parameters");
289  }
290  else if(obj.type() == OBJECT_ID)
291  {
292  OID dom_par_oid;
293  BER_Decoder(bits, len).decode(dom_par_oid);
294  return ec_group_data().lookup(dom_par_oid);
295  }
296  else if(obj.type() == SEQUENCE)
297  {
298  BigInt p, a, b, order, cofactor;
299  std::vector<uint8_t> base_pt;
300  std::vector<uint8_t> seed;
301 
302  BER_Decoder(bits, len)
303  .start_cons(SEQUENCE)
304  .decode_and_check<size_t>(1, "Unknown ECC param version code")
305  .start_cons(SEQUENCE)
306  .decode_and_check(OID("1.2.840.10045.1.1"),
307  "Only prime ECC fields supported")
308  .decode(p)
309  .end_cons()
310  .start_cons(SEQUENCE)
311  .decode_octet_string_bigint(a)
312  .decode_octet_string_bigint(b)
313  .decode_optional_string(seed, BIT_STRING, BIT_STRING)
314  .end_cons()
315  .decode(base_pt, OCTET_STRING)
316  .decode(order)
317  .decode(cofactor)
318  .end_cons()
319  .verify_end();
320 
321 #if defined(BOTAN_HAS_SYSTEM_RNG)
322  System_RNG rng;
323 #elif defined(BOTAN_HAS_HMAC_DRBG) && defined(BOTAN_HAS_SHA2_32)
324  /*
325  * This is not ideal because the data is attacker controlled, but
326  * it seems like it would be difficult for someone to come up
327  * with an valid ASN.1 encoding where the prime happened to pass
328  * Miller-Rabin test with exactly the values chosen when
329  * HMAC_DRBG is seeded with the overall data.
330  */
331  HMAC_DRBG rng("SHA-256");
332  rng.add_entropy(bits, len);
333 #else
334  Null_RNG rng;
335 #endif
336 
337  if(p.bits() < 64 || p.is_negative() || (is_prime(p, rng) == false))
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)
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, order, cofactor, OID());
355  }
356  else
357  {
358  throw Decoding_Error("Unexpected tag while decoding ECC domain params");
359  }
360  }
361 
363  {
364  }
365 
367  {
368  // shared_ptr possibly freed here
369  }
370 
371 EC_Group::EC_Group(const OID& domain_oid)
372  {
373  this->m_data = ec_group_data().lookup(domain_oid);
374  if(!this->m_data)
375  throw Invalid_Argument("Unknown EC_Group " + domain_oid.as_string());
376  }
377 
378 EC_Group::EC_Group(const std::string& str)
379  {
380  if(str == "")
381  return; // no initialization / uninitialized
382 
383  try
384  {
385  OID oid = OIDS::lookup(str);
386  if(oid.empty() == false)
387  m_data = ec_group_data().lookup(oid);
388  }
389  catch(Invalid_OID&)
390  {
391  }
392 
393  if(m_data == nullptr)
394  {
395  if(str.size() > 30 && str.substr(0, 29) == "-----BEGIN EC PARAMETERS-----")
396  {
397  // OK try it as PEM ...
398  secure_vector<uint8_t> ber = PEM_Code::decode_check_label(str, "EC PARAMETERS");
399  this->m_data = BER_decode_EC_group(ber.data(), ber.size());
400  }
401  }
402 
403  if(m_data == nullptr)
404  throw Invalid_Argument("Unknown ECC group '" + str + "'");
405  }
406 
407 //static
408 std::string EC_Group::PEM_for_named_group(const std::string& name)
409  {
410  try
411  {
412  EC_Group group(name);
413  return group.PEM_encode();
414  }
415  catch(...)
416  {
417  return "";
418  }
419  }
420 
422  const BigInt& a,
423  const BigInt& b,
424  const BigInt& base_x,
425  const BigInt& base_y,
426  const BigInt& order,
427  const BigInt& cofactor,
428  const OID& oid)
429  {
430  m_data = ec_group_data().lookup_or_create(p, a, b, base_x, base_y, order, cofactor, oid);
431  }
432 
433 EC_Group::EC_Group(const std::vector<uint8_t>& ber)
434  {
435  m_data = BER_decode_EC_group(ber.data(), ber.size());
436  }
437 
438 const EC_Group_Data& EC_Group::data() const
439  {
440  if(m_data == nullptr)
441  throw Invalid_State("EC_Group uninitialized");
442  return *m_data;
443  }
444 
446  {
447  return data().curve();
448  }
449 
451  {
452  return data().a_is_minus_3();
453  }
454 
456  {
457  return data().a_is_zero();
458  }
459 
460 size_t EC_Group::get_p_bits() const
461  {
462  return data().p_bits();
463  }
464 
465 size_t EC_Group::get_p_bytes() const
466  {
467  return data().p_bytes();
468  }
469 
471  {
472  return data().order_bits();
473  }
474 
476  {
477  return data().order_bytes();
478  }
479 
480 const BigInt& EC_Group::get_p() const
481  {
482  return data().p();
483  }
484 
485 const BigInt& EC_Group::get_a() const
486  {
487  return data().a();
488  }
489 
490 const BigInt& EC_Group::get_b() const
491  {
492  return data().b();
493  }
494 
496  {
497  return data().base_point();
498  }
499 
501  {
502  return data().order();
503  }
504 
505 const BigInt& EC_Group::get_g_x() const
506  {
507  return data().g_x();
508  }
509 
510 const BigInt& EC_Group::get_g_y() const
511  {
512  return data().g_y();
513  }
514 
516  {
517  return data().cofactor();
518  }
519 
521  {
522  return data().mod_order(k);
523  }
524 
526  {
527  return data().square_mod_order(x);
528  }
529 
531  {
532  return data().multiply_mod_order(x, y);
533  }
534 
535 BigInt EC_Group::multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const
536  {
537  return data().multiply_mod_order(x, y, z);
538  }
539 
541  {
542  return data().inverse_mod_order(x);
543  }
544 
546  {
547  return data().oid();
548  }
549 
550 PointGFp EC_Group::OS2ECP(const uint8_t bits[], size_t len) const
551  {
552  return Botan::OS2ECP(bits, len, data().curve());
553  }
554 
555 PointGFp EC_Group::point(const BigInt& x, const BigInt& y) const
556  {
557  // TODO: randomize the representation?
558  return PointGFp(data().curve(), x, y);
559  }
560 
561 PointGFp EC_Group::point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const
562  {
564  return xy_mul.multi_exp(x, y);
565  }
566 
569  std::vector<BigInt>& ws) const
570  {
571  return data().blinded_base_point_multiply(k, rng, ws);
572  }
573 
576  std::vector<BigInt>& ws) const
577  {
578  const PointGFp pt = data().blinded_base_point_multiply(k, rng, ws);
579 
580  if(pt.is_zero())
581  return 0;
582  return pt.get_affine_x();
583  }
584 
586  {
587  return BigInt::random_integer(rng, 1, get_order());
588  }
589 
591  const BigInt& k,
593  std::vector<BigInt>& ws) const
594  {
595  PointGFp_Var_Point_Precompute mul(point, rng, ws);
596  return mul.mul(k, rng, get_order(), ws);
597  }
598 
600  {
601  return PointGFp(data().curve());
602  }
603 
604 std::vector<uint8_t>
606  {
607  std::vector<uint8_t> output;
608 
609  DER_Encoder der(output);
610 
611  if(form == EC_DOMPAR_ENC_EXPLICIT)
612  {
613  const size_t ecpVers1 = 1;
614  const OID curve_type("1.2.840.10045.1.1"); // prime field
615 
616  const size_t p_bytes = get_p_bytes();
617 
618  der.start_cons(SEQUENCE)
619  .encode(ecpVers1)
621  .encode(curve_type)
622  .encode(get_p())
623  .end_cons()
625  .encode(BigInt::encode_1363(get_a(), p_bytes),
626  OCTET_STRING)
627  .encode(BigInt::encode_1363(get_b(), p_bytes),
628  OCTET_STRING)
629  .end_cons()
631  .encode(get_order())
632  .encode(get_cofactor())
633  .end_cons();
634  }
635  else if(form == EC_DOMPAR_ENC_OID)
636  {
637  const OID oid = get_curve_oid();
638  if(oid.empty())
639  {
640  throw Encoding_Error("Cannot encode EC_Group as OID because OID not set");
641  }
642  der.encode(oid);
643  }
644  else if(form == EC_DOMPAR_ENC_IMPLICITCA)
645  {
646  der.encode_null();
647  }
648  else
649  {
650  throw Internal_Error("EC_Group::DER_encode: Unknown encoding");
651  }
652 
653  return output;
654  }
655 
656 std::string EC_Group::PEM_encode() const
657  {
658  const std::vector<uint8_t> der = DER_encode(EC_DOMPAR_ENC_EXPLICIT);
659  return PEM_Code::encode(der, "EC PARAMETERS");
660  }
661 
662 bool EC_Group::operator==(const EC_Group& other) const
663  {
664  if(m_data == other.m_data)
665  return true; // same shared rep
666 
667  /*
668  * No point comparing order/cofactor as they are uniquely determined
669  * by the curve equation (p,a,b) and the base point.
670  */
671  return (get_p() == other.get_p() &&
672  get_a() == other.get_a() &&
673  get_b() == other.get_b() &&
674  get_g_x() == other.get_g_x() &&
675  get_g_y() == other.get_g_y());
676  }
677 
679  {
680  //check that public point is not at infinity
681  if(point.is_zero())
682  return false;
683 
684  //check that public point is on the curve
685  if(point.on_the_curve() == false)
686  return false;
687 
688  //check that public point has order q
689  if((point * get_order()).is_zero() == false)
690  return false;
691 
692  if(get_cofactor() > 1)
693  {
694  if((point * get_cofactor()).is_zero())
695  return false;
696  }
697 
698  return true;
699  }
700 
702  bool) const
703  {
704  const BigInt& p = get_p();
705  const BigInt& a = get_a();
706  const BigInt& b = get_b();
707  const BigInt& order = get_order();
708  const PointGFp& base_point = get_base_point();
709 
710  if(a < 0 || a >= p)
711  return false;
712  if(b <= 0 || b >= p)
713  return false;
714  if(order <= 0)
715  return false;
716 
717  //check if field modulus is prime
718  if(!is_prime(p, rng, 128))
719  {
720  return false;
721  }
722 
723  //check if order is prime
724  if(!is_prime(order, rng, 128))
725  {
726  return false;
727  }
728 
729  //compute the discriminant: 4*a^3 + 27*b^2 which must be nonzero
730  const Modular_Reducer mod_p(p);
731 
732  const BigInt discriminant = mod_p.reduce(
733  mod_p.multiply(4, mod_p.cube(a)) +
734  mod_p.multiply(27, mod_p.square(b)));
735 
736  if(discriminant == 0)
737  {
738  return false;
739  }
740 
741  //check for valid cofactor
742  if(get_cofactor() < 1)
743  {
744  return false;
745  }
746 
747  //check if the base point is on the curve
748  if(!base_point.on_the_curve())
749  {
750  return false;
751  }
752  if((base_point * get_cofactor()).is_zero())
753  {
754  return false;
755  }
756  //check if order of the base point is correct
757  if(!(base_point * order).is_zero())
758  {
759  return false;
760  }
761 
762  return true;
763  }
764 
765 }
BigInt cube(const BigInt &x) const
Definition: reducer.h:47
size_t get_p_bytes() const
Definition: ec_group.cpp:465
const OID & get_curve_oid() const
Definition: ec_group.cpp:545
PointGFp point(const BigInt &x, const BigInt &y) const
Definition: ec_group.cpp:555
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:460
BigInt multiply_mod_order(const BigInt &x, const BigInt &y) const
Definition: ec_group.cpp:530
BigInt mod_order(const BigInt &x) const
Definition: ec_group.cpp:520
const BigInt & get_order() const
Definition: ec_group.cpp:500
bool a_is_zero() const
Definition: ec_group.cpp:455
noop_mutex mutex_type
Definition: mutex.h:51
std::string as_string() const
Definition: asn1_oid.h:48
BigInt blinded_base_point_multiply_x(const BigInt &k, RandomNumberGenerator &rng, std::vector< BigInt > &ws) const
Definition: ec_group.cpp:574
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
Definition: numthry.cpp:507
const CurveGFp & get_curve() const
Definition: ec_group.cpp:445
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
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:408
PointGFp point_multiply(const BigInt &x, const PointGFp &pt, const BigInt &y) const
Definition: ec_group.cpp:561
bool a_is_minus_3() const
Definition: ec_group.cpp:450
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 verify_public_element(const PointGFp &y) const
Definition: ec_group.cpp:678
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:585
std::string PEM_encode() const
Definition: ec_group.cpp:656
const PointGFp & get_base_point() const
Definition: ec_group.cpp:495
size_t get_order_bits() const
Definition: ec_group.cpp:470
bool empty() const
Definition: asn1_oid.h:30
const BigInt & get_cofactor() const
Definition: ec_group.cpp:515
DER_Encoder & encode_null()
Definition: der_enc.cpp:277
PointGFp OS2ECP(const uint8_t bits[], size_t len) const
Definition: ec_group.cpp:550
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition: numthry.cpp:288
Definition: alg_id.cpp:13
const BigInt & get_b() const
Definition: ec_group.cpp:490
BigInt square_mod_order(const BigInt &x) const
Definition: ec_group.cpp:525
T is_zero(T x)
Definition: ct_utils.h:130
const BigInt & get_g_x() const
Definition: ec_group.cpp:505
bool on_the_curve() const
Definition: point_gfp.cpp:540
const BigInt & get_a() const
Definition: ec_group.cpp:485
const BigInt & get_g_y() const
Definition: ec_group.cpp:510
EC_Group_Encoding
Definition: ec_group.h:23
const BigInt & get_p() const
Definition: ec_group.cpp:480
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:38
PointGFp blinded_var_point_multiply(const PointGFp &point, const BigInt &k, RandomNumberGenerator &rng, std::vector< BigInt > &ws) const
Definition: ec_group.cpp:590
size_t get_order_bytes() const
Definition: ec_group.cpp:475
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:82
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:662
BigInt square(const BigInt &x) const
Definition: reducer.h:39
bool verify_group(RandomNumberGenerator &rng, bool strong=false) const
Definition: ec_group.cpp:701
BigInt multiply(const BigInt &x, const BigInt &y) const
Definition: reducer.h:31
PointGFp zero_point() const
Definition: ec_group.cpp:599
std::vector< uint8_t > DER_encode(EC_Group_Encoding form) const
Definition: ec_group.cpp:605
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:567
static size_t clear_registered_curve_data()
Definition: ec_group.cpp:254
BigInt inverse_mod_order(const BigInt &x) const
Definition: ec_group.cpp:540