Botan 2.19.4
Crypto and TLS for C&
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
22namespace Botan {
23
24class 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
143class 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
256EC_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
275std::shared_ptr<EC_Group_Data>
276EC_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
296std::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() < 112 || p.bits() > 1024)
338 throw Decoding_Error("ECC p parameter is invalid size");
339
340 if(p.is_negative() || !is_bailie_psw_probable_prime(p))
341 throw Decoding_Error("ECC p parameter is not a prime");
342
343 if(a.is_negative() || a >= p)
344 throw Decoding_Error("Invalid ECC a parameter");
345
346 if(b <= 0 || b >= p)
347 throw Decoding_Error("Invalid ECC b parameter");
348
349 if(order <= 0 || !is_bailie_psw_probable_prime(order))
350 throw Decoding_Error("Invalid ECC order parameter");
351
352 if(cofactor <= 0 || cofactor >= 16)
353 throw Decoding_Error("Invalid ECC cofactor parameter");
354
355 std::pair<BigInt, BigInt> base_xy = Botan::OS2ECP(base_pt.data(), base_pt.size(), p, a, b);
356
357 return ec_group_data().lookup_or_create(p, a, b, base_xy.first, base_xy.second,
358 order, cofactor, OID(), source);
359 }
360 else
361 {
362 throw Decoding_Error("Unexpected tag while decoding ECC domain params");
363 }
364 }
365
367 {
368 }
369
371 {
372 // shared_ptr possibly freed here
373 }
374
375EC_Group::EC_Group(const OID& domain_oid)
376 {
377 this->m_data = ec_group_data().lookup(domain_oid);
378 if(!this->m_data)
379 throw Invalid_Argument("Unknown EC_Group " + domain_oid.to_string());
380 }
381
382EC_Group::EC_Group(const std::string& str)
383 {
384 if(str == "")
385 return; // no initialization / uninitialized
386
387 try
388 {
389 const OID oid = OID::from_string(str);
390 if(oid.has_value())
391 m_data = ec_group_data().lookup(oid);
392 }
393 catch(...)
394 {
395 }
396
397 if(m_data == nullptr)
398 {
399 if(str.size() > 30 && str.substr(0, 29) == "-----BEGIN EC PARAMETERS-----")
400 {
401 // OK try it as PEM ...
402 secure_vector<uint8_t> ber = PEM_Code::decode_check_label(str, "EC PARAMETERS");
403 this->m_data = BER_decode_EC_group(ber.data(), ber.size(), EC_Group_Source::ExternalSource);
404 }
405 }
406
407 if(m_data == nullptr)
408 throw Invalid_Argument("Unknown ECC group '" + str + "'");
409 }
410
411//static
413 {
414 const auto ber = PEM_Code::decode_check_label(pem, "EC PARAMETERS");
415 return EC_Group(ber.data(), ber.size());
416 }
417
418//static
419std::string EC_Group::PEM_for_named_group(const std::string& name)
420 {
421 try
422 {
423 EC_Group group(name);
424 return group.PEM_encode();
425 }
426 catch(...)
427 {
428 return "";
429 }
430 }
431
433 const BigInt& a,
434 const BigInt& b,
435 const BigInt& base_x,
436 const BigInt& base_y,
437 const BigInt& order,
438 const BigInt& cofactor,
439 const OID& oid)
440 {
441 m_data = ec_group_data().lookup_or_create(p, a, b, base_x, base_y, order, cofactor, oid,
443 }
444
445EC_Group::EC_Group(const uint8_t ber[], size_t ber_len)
446 {
447 m_data = BER_decode_EC_group(ber, ber_len, EC_Group_Source::ExternalSource);
448 }
449
450const EC_Group_Data& EC_Group::data() const
451 {
452 if(m_data == nullptr)
453 throw Invalid_State("EC_Group uninitialized");
454 return *m_data;
455 }
456
458 {
459 return data().curve();
460 }
461
463 {
464 return data().a_is_minus_3();
465 }
466
468 {
469 return data().a_is_zero();
470 }
471
473 {
474 return data().p_bits();
475 }
476
478 {
479 return data().p_bytes();
480 }
481
483 {
484 return data().order_bits();
485 }
486
488 {
489 return data().order_bytes();
490 }
491
493 {
494 return data().p();
495 }
496
498 {
499 return data().a();
500 }
501
503 {
504 return data().b();
505 }
506
508 {
509 return data().base_point();
510 }
511
513 {
514 return data().order();
515 }
516
518 {
519 return data().g_x();
520 }
521
523 {
524 return data().g_y();
525 }
526
528 {
529 return data().cofactor();
530 }
531
533 {
534 return data().mod_order(k);
535 }
536
538 {
539 return data().square_mod_order(x);
540 }
541
543 {
544 return data().multiply_mod_order(x, y);
545 }
546
547BigInt EC_Group::multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const
548 {
549 return data().multiply_mod_order(x, y, z);
550 }
551
553 {
554 return data().inverse_mod_order(x);
555 }
556
558 {
559 return data().oid();
560 }
561
563 {
564 return data().source();
565 }
566
568 {
569 // Hybrid and standard format are (x,y), compressed is y, +1 format byte
570 if(format == PointGFp::COMPRESSED)
571 return (1 + get_p_bytes());
572 else
573 return (1 + 2*get_p_bytes());
574 }
575
576PointGFp EC_Group::OS2ECP(const uint8_t bits[], size_t len) const
577 {
578 return Botan::OS2ECP(bits, len, data().curve());
579 }
580
581PointGFp EC_Group::point(const BigInt& x, const BigInt& y) const
582 {
583 // TODO: randomize the representation?
584 return PointGFp(data().curve(), x, y);
585 }
586
587PointGFp EC_Group::point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const
588 {
590 return xy_mul.multi_exp(x, y);
591 }
592
595 std::vector<BigInt>& ws) const
596 {
597 return data().blinded_base_point_multiply(k, rng, ws);
598 }
599
602 std::vector<BigInt>& ws) const
603 {
604 const PointGFp pt = data().blinded_base_point_multiply(k, rng, ws);
605
606 if(pt.is_zero())
607 return 0;
608 return pt.get_affine_x();
609 }
610
612 {
613 return BigInt::random_integer(rng, 1, get_order());
614 }
615
617 const BigInt& k,
619 std::vector<BigInt>& ws) const
620 {
622 return mul.mul(k, rng, get_order(), ws);
623 }
624
626 {
627 return PointGFp(data().curve());
628 }
629
630std::vector<uint8_t>
632 {
633 std::vector<uint8_t> output;
634
635 DER_Encoder der(output);
636
637 if(form == EC_DOMPAR_ENC_EXPLICIT)
638 {
639 const size_t ecpVers1 = 1;
640 const OID curve_type("1.2.840.10045.1.1"); // prime field
641
642 const size_t p_bytes = get_p_bytes();
643
645 .encode(ecpVers1)
647 .encode(curve_type)
648 .encode(get_p())
649 .end_cons()
651 .encode(BigInt::encode_1363(get_a(), p_bytes),
653 .encode(BigInt::encode_1363(get_b(), p_bytes),
655 .end_cons()
657 .encode(get_order())
659 .end_cons();
660 }
661 else if(form == EC_DOMPAR_ENC_OID)
662 {
663 const OID oid = get_curve_oid();
664 if(oid.empty())
665 {
666 throw Encoding_Error("Cannot encode EC_Group as OID because OID not set");
667 }
668 der.encode(oid);
669 }
670 else if(form == EC_DOMPAR_ENC_IMPLICITCA)
671 {
672 der.encode_null();
673 }
674 else
675 {
676 throw Internal_Error("EC_Group::DER_encode: Unknown encoding");
677 }
678
679 return output;
680 }
681
682std::string EC_Group::PEM_encode() const
683 {
684 const std::vector<uint8_t> der = DER_encode(EC_DOMPAR_ENC_EXPLICIT);
685 return PEM_Code::encode(der, "EC PARAMETERS");
686 }
687
688bool EC_Group::operator==(const EC_Group& other) const
689 {
690 if(m_data == other.m_data)
691 return true; // same shared rep
692
693 /*
694 * No point comparing order/cofactor as they are uniquely determined
695 * by the curve equation (p,a,b) and the base point.
696 */
697 return (get_p() == other.get_p() &&
698 get_a() == other.get_a() &&
699 get_b() == other.get_b() &&
700 get_g_x() == other.get_g_x() &&
701 get_g_y() == other.get_g_y());
702 }
703
705 {
706 //check that public point is not at infinity
707 if(point.is_zero())
708 return false;
709
710 //check that public point is on the curve
711 if(point.on_the_curve() == false)
712 return false;
713
714 //check that public point has order q
715 if((point * get_order()).is_zero() == false)
716 return false;
717
718 if(get_cofactor() > 1)
719 {
720 if((point * get_cofactor()).is_zero())
721 return false;
722 }
723
724 return true;
725 }
726
728 bool strong) const
729 {
730 const bool is_builtin = source() == EC_Group_Source::Builtin;
731
732 if(is_builtin && !strong)
733 return true;
734
735 const BigInt& p = get_p();
736 const BigInt& a = get_a();
737 const BigInt& b = get_b();
738 const BigInt& order = get_order();
739 const PointGFp& base_point = get_base_point();
740
741 if(p <= 3 || order <= 0)
742 return false;
743 if(a < 0 || a >= p)
744 return false;
745 if(b <= 0 || b >= p)
746 return false;
747
748 const size_t test_prob = 128;
749 const bool is_randomly_generated = is_builtin;
750
751 //check if field modulus is prime
752 if(!is_prime(p, rng, test_prob, is_randomly_generated))
753 {
754 return false;
755 }
756
757 //check if order is prime
758 if(!is_prime(order, rng, test_prob, is_randomly_generated))
759 {
760 return false;
761 }
762
763 //compute the discriminant: 4*a^3 + 27*b^2 which must be nonzero
764 const Modular_Reducer mod_p(p);
765
766 const BigInt discriminant = mod_p.reduce(
767 mod_p.multiply(4, mod_p.cube(a)) +
768 mod_p.multiply(27, mod_p.square(b)));
769
770 if(discriminant == 0)
771 {
772 return false;
773 }
774
775 //check for valid cofactor
776 if(get_cofactor() < 1)
777 {
778 return false;
779 }
780
781 //check if the base point is on the curve
782 if(!base_point.on_the_curve())
783 {
784 return false;
785 }
786 if((base_point * get_cofactor()).is_zero())
787 {
788 return false;
789 }
790 //check if order of the base point is correct
791 if(!(base_point * order).is_zero())
792 {
793 return false;
794 }
795
796 return true;
797 }
798
799}
#define BOTAN_STATE_CHECK(expr)
Definition: assert.h:49
static BigInt random_integer(RandomNumberGenerator &rng, const BigInt &min, const BigInt &max)
Definition: big_rand.cpp:45
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:111
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition: der_enc.cpp:181
DER_Encoder & encode_null()
Definition: der_enc.cpp:277
DER_Encoder & end_cons()
Definition: der_enc.cpp:191
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:285
PointGFp OS2ECP(const uint8_t bits[], size_t len) const
Definition: ec_group.cpp:576
bool a_is_minus_3() const
Definition: ec_group.cpp:462
BigInt blinded_base_point_multiply_x(const BigInt &k, RandomNumberGenerator &rng, std::vector< BigInt > &ws) const
Definition: ec_group.cpp:600
const BigInt & get_b() const
Definition: ec_group.cpp:502
const BigInt & get_a() const
Definition: ec_group.cpp:497
const BigInt & get_g_y() const
Definition: ec_group.cpp:522
PointGFp blinded_base_point_multiply(const BigInt &k, RandomNumberGenerator &rng, std::vector< BigInt > &ws) const
Definition: ec_group.cpp:593
const BigInt & get_cofactor() const
Definition: ec_group.cpp:527
BigInt mod_order(const BigInt &x) const
Definition: ec_group.cpp:532
bool operator==(const EC_Group &other) const
Definition: ec_group.cpp:688
BigInt multiply_mod_order(const BigInt &x, const BigInt &y) const
Definition: ec_group.cpp:542
EC_Group_Source source() const
Definition: ec_group.cpp:562
bool a_is_zero() const
Definition: ec_group.cpp:467
PointGFp point_multiply(const BigInt &x, const PointGFp &pt, const BigInt &y) const
Definition: ec_group.cpp:587
static std::string PEM_for_named_group(const std::string &name)
Definition: ec_group.cpp:419
const BigInt & get_p() const
Definition: ec_group.cpp:492
static EC_Group EC_Group_from_PEM(const std::string &pem)
Definition: ec_group.cpp:412
bool verify_group(RandomNumberGenerator &rng, bool strong=false) const
Definition: ec_group.cpp:727
PointGFp point(const BigInt &x, const BigInt &y) const
Definition: ec_group.cpp:581
size_t point_size(PointGFp::Compression_Type format) const
Definition: ec_group.cpp:567
const BigInt & get_order() const
Definition: ec_group.cpp:512
size_t get_p_bits() const
Definition: ec_group.cpp:472
bool verify_public_element(const PointGFp &y) const
Definition: ec_group.cpp:704
static std::shared_ptr< EC_Group_Data > EC_group_info(const OID &oid)
Definition: ec_named.cpp:13
std::string PEM_encode() const
Definition: ec_group.cpp:682
const BigInt & get_g_x() const
Definition: ec_group.cpp:517
const OID & get_curve_oid() const
Definition: ec_group.cpp:557
BigInt square_mod_order(const BigInt &x) const
Definition: ec_group.cpp:537
const PointGFp & get_base_point() const
Definition: ec_group.cpp:507
static size_t clear_registered_curve_data()
Definition: ec_group.cpp:269
std::vector< uint8_t > DER_encode(EC_Group_Encoding form) const
Definition: ec_group.cpp:631
BigInt inverse_mod_order(const BigInt &x) const
Definition: ec_group.cpp:552
PointGFp zero_point() const
Definition: ec_group.cpp:625
const CurveGFp & get_curve() const
Definition: ec_group.cpp:457
size_t get_p_bytes() const
Definition: ec_group.cpp:477
PointGFp blinded_var_point_multiply(const PointGFp &point, const BigInt &k, RandomNumberGenerator &rng, std::vector< BigInt > &ws) const
Definition: ec_group.cpp:616
BigInt random_scalar(RandomNumberGenerator &rng) const
Definition: ec_group.cpp:611
size_t get_order_bits() const
Definition: ec_group.cpp:482
size_t get_order_bytes() const
Definition: ec_group.cpp:487
BigInt cube(const BigInt &x) const
Definition: reducer.h:47
BigInt square(const BigInt &x) const
Definition: reducer.h:39
BigInt multiply(const BigInt &x, const BigInt &y) const
Definition: reducer.h:31
BigInt reduce(const BigInt &x) const
Definition: reducer.cpp:37
bool has_value() const
Definition: asn1_obj.h:238
bool empty() const
Definition: asn1_obj.h:232
static OID from_string(const std::string &str)
Definition: asn1_oid.cpp:62
std::string to_string() const
Definition: asn1_oid.cpp:98
PointGFp multi_exp(const BigInt &k1, const BigInt &k2) const
Definition: point_mul.cpp:394
PointGFp mul(const BigInt &k, RandomNumberGenerator &rng, const BigInt &group_order, std::vector< BigInt > &ws) const
Definition: point_mul.cpp:267
bool on_the_curve() const
Definition: point_gfp.cpp:544
BigInt get_affine_x() const
Definition: point_gfp.cpp:505
bool is_zero() const
Definition: point_gfp.h:184
std::string name
int(* final)(unsigned char *, CTX *)
std::string lookup(const OID &oid)
Definition: oids.h:71
std::string encode(const uint8_t der[], size_t length, const std::string &label, size_t width)
Definition: pem.cpp:43
secure_vector< uint8_t > decode_check_label(DataSource &source, const std::string &label_want)
Definition: pem.cpp:54
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
Definition: pem.cpp:68
Definition: alg_id.cpp:13
EC_Group_Source
Definition: ec_group.h:29
PointGFp OS2ECP(const uint8_t data[], size_t data_len, const CurveGFp &curve)
Definition: point_gfp.cpp:667
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
Definition: numthry.cpp:218
bool is_bailie_psw_probable_prime(const BigInt &n, const Modular_Reducer &mod_n)
Definition: primality.cpp:92
@ BIT_STRING
Definition: asn1_obj.h:37
@ SEQUENCE
Definition: asn1_obj.h:42
@ OCTET_STRING
Definition: asn1_obj.h:38
@ NULL_TAG
Definition: asn1_obj.h:39
@ OBJECT_ID
Definition: asn1_obj.h:40
EC_Group_Encoding
Definition: ec_group.h:23
@ EC_DOMPAR_ENC_EXPLICIT
Definition: ec_group.h:24
@ EC_DOMPAR_ENC_OID
Definition: ec_group.h:26
@ EC_DOMPAR_ENC_IMPLICITCA
Definition: ec_group.h:25
noop_mutex mutex_type
Definition: mutex.h:52
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition: mod_inv.cpp:250
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:65