Botan 3.12.0
Crypto and TLS for C&
dl_group.cpp
Go to the documentation of this file.
1/*
2* Discrete Logarithm Parameters
3* (C) 1999-2008,2015,2018 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/dl_group.h>
9
10#include <botan/ber_dec.h>
11#include <botan/der_enc.h>
12#include <botan/numthry.h>
13#include <botan/pem.h>
14#include <botan/internal/barrett.h>
15#include <botan/internal/divide.h>
16#include <botan/internal/fmt.h>
17#include <botan/internal/mod_inv.h>
18#include <botan/internal/monty.h>
19#include <botan/internal/monty_exp.h>
20#include <botan/internal/primality.h>
21#include <botan/internal/workfactor.h>
22#include <string_view>
23
24namespace Botan {
25
26namespace {
27
28void check_dl_group_params(const BigInt& p, const BigInt& g) {
29 if(p.signum() <= 0 || p.is_even() || p.bits() < 3 || p.bits() > 16384) {
30 throw Decoding_Error("Invalid DL group prime");
31 }
32 if(g.signum() <= 0 || g < 2 || g >= p) {
33 throw Decoding_Error("Invalid DL group generator");
34 }
35}
36
37void check_dl_group_params(const BigInt& p, const BigInt& q, const BigInt& g) {
38 check_dl_group_params(p, g);
39 if(q.signum() <= 0 || q.is_even() || q.bits() >= p.bits()) {
40 throw Decoding_Error("Invalid DL group subgroup order");
41 }
42}
43
44} // namespace
45
46class DL_Group_Data final {
47 public:
48 static std::shared_ptr<DL_Group_Data> create(const BigInt& p,
49 const BigInt& q,
50 const BigInt& g,
51 DL_Group_Source source) {
52 check_dl_group_params(p, q, g);
53 return std::make_shared<DL_Group_Data>(p, q, g, source);
54 }
55
56 static std::shared_ptr<DL_Group_Data> create(const BigInt& p, const BigInt& g, DL_Group_Source source) {
57 check_dl_group_params(p, g);
58 return std::make_shared<DL_Group_Data>(p, g, source);
59 }
60
61 // This constructor is public because C++ is terrible but all DL_Group_Data should
62 // be created via DL_Group_Data::create
63 DL_Group_Data(const BigInt& p, const BigInt& q, const BigInt& g, DL_Group_Source source) :
64 m_p(p),
65 m_q(q),
66 m_g(g),
67 m_mod_p(Barrett_Reduction::for_public_modulus(p)),
68 m_mod_q(Barrett_Reduction::for_public_modulus(q)),
69 m_monty_params(m_p, m_mod_p),
70 m_monty(monty_precompute(m_monty_params, m_g, /*window bits=*/4)),
71 m_p_bits(p.bits()),
72 m_q_bits(q.bits()),
73 m_estimated_strength(dl_work_factor(m_p_bits)),
74 m_exponent_bits(dl_exponent_size(m_p_bits)),
75 m_source(source) {}
76
77 // This constructor is public because C++ is terrible but all DL_Group_Data should
78 // be created via DL_Group_Data::create
79 DL_Group_Data(const BigInt& p, const BigInt& g, DL_Group_Source source) :
80 m_p(p),
81 m_g(g),
82 m_mod_p(Barrett_Reduction::for_public_modulus(p)),
83 m_monty_params(m_p, m_mod_p),
84 m_monty(monty_precompute(m_monty_params, m_g, /*window bits=*/4)),
85 m_p_bits(p.bits()),
86 m_q_bits(0),
87 m_estimated_strength(dl_work_factor(m_p_bits)),
88 m_exponent_bits(dl_exponent_size(m_p_bits)),
89 m_source(source) {}
90
91 ~DL_Group_Data() = default;
92
93 DL_Group_Data(const DL_Group_Data& other) = delete;
94 DL_Group_Data(DL_Group_Data&& other) = delete;
95 DL_Group_Data& operator=(const DL_Group_Data& other) = delete;
96 DL_Group_Data& operator=(DL_Group_Data&& other) = delete;
97
98 const BigInt& p() const { return m_p; }
99
100 const BigInt& q() const { return m_q; }
101
102 const BigInt& g() const { return m_g; }
103
104 const Barrett_Reduction& reducer_mod_p() const { return m_mod_p; }
105
106 const Barrett_Reduction& reducer_mod_q() const {
107 BOTAN_STATE_CHECK(m_mod_q);
108 return *m_mod_q;
109 }
110
111 const Montgomery_Params& monty_params_p() const { return m_monty_params; }
112
113 size_t p_bits() const { return m_p_bits; }
114
115 size_t q_bits() const { return m_q_bits; }
116
117 size_t p_bytes() const { return (m_p_bits + 7) / 8; }
118
119 size_t q_bytes() const { return (m_q_bits + 7) / 8; }
120
121 size_t estimated_strength() const { return m_estimated_strength; }
122
123 size_t exponent_bits() const { return m_exponent_bits; }
124
125 BigInt power_g_p(const BigInt& k, size_t max_k_bits) const {
126 return monty_execute(*m_monty, k, max_k_bits).value();
127 }
128
129 BigInt power_g_p_vartime(const BigInt& k) const { return monty_execute_vartime(*m_monty, k).value(); }
130
131 BigInt power_b_p(const BigInt& b, const BigInt& k, size_t max_k_bits) const {
132 return monty_exp(m_monty_params, b, k, max_k_bits).value();
133 }
134
135 BigInt power_b_p_vartime(const BigInt& b, const BigInt& k) const {
136 return monty_exp_vartime(m_monty_params, b, k).value();
137 }
138
139 bool q_is_set() const { return m_q_bits > 0; }
140
141 void assert_q_is_set(std::string_view function) const {
142 if(!q_is_set()) {
143 throw Invalid_State(fmt("DL_Group::{}: q is not set for this group", function));
144 }
145 }
146
147 DL_Group_Source source() const { return m_source; }
148
149 private:
150 BigInt m_p;
151 BigInt m_q; // zero if no q set
152 BigInt m_g;
153 Barrett_Reduction m_mod_p;
154 std::optional<Barrett_Reduction> m_mod_q;
155 Montgomery_Params m_monty_params;
156 std::shared_ptr<const Montgomery_Exponentiation_State> m_monty;
157 size_t m_p_bits;
158 size_t m_q_bits;
159 size_t m_estimated_strength;
160 size_t m_exponent_bits;
161 DL_Group_Source m_source;
162};
163
164//static
165std::shared_ptr<DL_Group_Data> DL_Group::DER_decode_DL_group(const std::span<const uint8_t> data,
166 DL_Group_Format format,
167 DL_Group_Source source) {
168 BER_Decoder decoder(data, BER_Decoder::Limits::DER());
169 BER_Decoder inner = decoder.start_sequence();
170
171 if(format == DL_Group_Format::ANSI_X9_57) {
172 /*
173 This format is p, q, g with no additional data following
174 */
175 BigInt p;
176 BigInt q;
177 BigInt g;
178 inner.decode(p).decode(q).decode(g).verify_end();
179 return DL_Group_Data::create(p, q, g, source);
180 } else if(format == DL_Group_Format::ANSI_X9_42) {
181 /*
182 This format is p, g, q with optional cofactor and seed following
183 */
184 BigInt p;
185 BigInt g;
186 BigInt q;
187 inner.decode(p).decode(g).decode(q).discard_remaining();
188 return DL_Group_Data::create(p, q, g, source);
189 } else if(format == DL_Group_Format::PKCS_3) {
190 /*
191 This format is p, g followed by optional privateValueLength (recommended exponent size)
192 */
193 BigInt p;
194 BigInt g;
195 inner.decode(p).decode(g).discard_remaining();
196 return DL_Group_Data::create(p, g, source);
197 } else {
198 throw Invalid_Argument("Unknown DL_Group encoding");
199 }
200}
201
202//static
203std::shared_ptr<DL_Group_Data> DL_Group::load_DL_group_info(const char* p_str, const char* q_str, const char* g_str) {
204 const BigInt p(p_str);
205 const BigInt q(q_str);
206 const BigInt g(g_str);
207
208 if(q.is_zero()) {
209 return DL_Group_Data::create(p, g, DL_Group_Source::Builtin);
210 } else {
211 return DL_Group_Data::create(p, q, g, DL_Group_Source::Builtin);
212 }
213}
214
215//static
216std::shared_ptr<DL_Group_Data> DL_Group::load_DL_group_info(const char* p_str, const char* g_str) {
217 const BigInt p(p_str);
218 const BigInt q = (p - 1) / 2;
219 const BigInt g(g_str);
220
221 return DL_Group_Data::create(p, q, g, DL_Group_Source::Builtin);
222}
223
224namespace {
225
226DL_Group_Format pem_label_to_dl_format(std::string_view label) {
227 if(label == "DH PARAMETERS") {
229 } else if(label == "DSA PARAMETERS") {
231 } else if(label == "X942 DH PARAMETERS" || label == "X9.42 DH PARAMETERS") {
233 } else {
234 throw Decoding_Error(fmt("DL_Group: Unknown PEM label '{}'", label));
235 }
236}
237
238} // namespace
239
240/*
241* DL_Group Constructor
242*/
243DL_Group::DL_Group(std::string_view str) {
244 // Either a name or a PEM block, try name first
245 m_data = DL_group_info(str);
246
247 if(m_data == nullptr) {
248 try {
249 std::string label;
250 const std::vector<uint8_t> der = unlock(PEM_Code::decode(str, label));
251 const DL_Group_Format format = pem_label_to_dl_format(label);
252
253 m_data = DER_decode_DL_group(der, format, DL_Group_Source::ExternalSource);
254 } catch(...) {}
255 }
256
257 if(m_data == nullptr) {
258 throw Invalid_Argument(fmt("DL_Group: Unknown group '{}'", str));
259 }
260}
261
262DL_Group DL_Group::from_name(std::string_view name) {
263 auto data = DL_group_info(name);
264
265 if(!data) {
266 throw Invalid_Argument(fmt("DL_Group: Unknown group '{}'", name));
267 }
268
269 return DL_Group(data);
270}
271
272//static
273DL_Group DL_Group::from_PEM(std::string_view pem) {
274 std::string label;
275 const std::vector<uint8_t> ber = unlock(PEM_Code::decode(pem, label));
276 const DL_Group_Format format = pem_label_to_dl_format(label);
277 return DL_Group(ber, format);
278}
279
280namespace {
281
282/*
283* Create generator of the q-sized subgroup (DSA style generator)
284*/
285BigInt make_dsa_generator(const BigInt& p, const BigInt& q) {
286 BigInt e;
287 BigInt r;
288 vartime_divide(p - 1, q, e, r);
289
290 if(e == 0 || r > 0) {
291 throw Invalid_Argument("make_dsa_generator q does not divide p-1");
292 }
293
294 // TODO we compute these, then throw them away and recompute in DL_Group_Data
296 const Montgomery_Params params(p, mod_p);
297
298 for(size_t i = 0; i != PRIME_TABLE_SIZE; ++i) {
299 BigInt g = monty_exp_vartime(params, BigInt::from_word(PRIMES[i]), e).value();
300 if(g > 1) {
301 return g;
302 }
303 }
304
305 throw Internal_Error("DL_Group: Couldn't create a suitable generator");
306}
307
308} // namespace
309
310/*
311* DL_Group Constructor
312*/
313DL_Group::DL_Group(RandomNumberGenerator& rng, PrimeType type, size_t pbits, size_t qbits) {
314 if(pbits < 1024) {
315 throw Invalid_Argument(fmt("DL_Group: requested prime size {} is too small", pbits));
316 }
317
318 if(qbits >= pbits) {
319 throw Invalid_Argument(fmt("DL_Group: requested q size {} is too big for p {}", qbits, pbits));
320 }
321
322 if(type == Strong) {
323 if(qbits != 0 && qbits != pbits - 1) {
324 throw Invalid_Argument("Cannot create strong-prime DL_Group with specified q bits");
325 }
326
327 const BigInt p = random_safe_prime(rng, pbits);
328 const BigInt q = (p - 1) / 2;
329
330 /*
331 Always choose a generator that is quadratic reside mod p, this forces g to
332 be a generator of the subgroup of size q.
333
334 We use 2 by default, but if 2 is not a quadratic reside then use 4 which
335 is always a quadratic reside, being the square of 2 (or p - 2)
336 */
338 if(jacobi(g, p) != 1) {
339 g = BigInt::from_word(4);
340 }
341
342 m_data = DL_Group_Data::create(p, q, g, DL_Group_Source::RandomlyGenerated);
343 } else if(type == Prime_Subgroup) {
344 if(qbits == 0) {
345 qbits = dl_exponent_size(pbits);
346 }
347
348 const BigInt q = random_prime(rng, qbits);
349 const BigInt q2 = q * 2;
350 BigInt X;
351 BigInt p;
352 while(p.bits() != pbits || !is_prime(p, rng, 128, true)) {
353 X.randomize(rng, pbits);
354 // Variable time division is OK here since DH groups are public anyway
355 p = X - (X % q2) + 1;
356 }
357
358 const BigInt g = make_dsa_generator(p, q);
359 m_data = DL_Group_Data::create(p, q, g, DL_Group_Source::RandomlyGenerated);
360 } else if(type == DSA_Kosherizer) {
361 if(qbits == 0) {
362 qbits = ((pbits <= 1024) ? 160 : 256);
363 }
364
365 BigInt p;
366 BigInt q;
367 generate_dsa_primes(rng, p, q, pbits, qbits);
368 const BigInt g = make_dsa_generator(p, q);
369 m_data = DL_Group_Data::create(p, q, g, DL_Group_Source::RandomlyGenerated);
370 } else {
371 throw Invalid_Argument("DL_Group unknown PrimeType");
372 }
373}
374
375/*
376* DL_Group Constructor
377*/
378DL_Group::DL_Group(RandomNumberGenerator& rng, const std::vector<uint8_t>& seed, size_t pbits, size_t qbits) {
379 BigInt p;
380 BigInt q;
381
382 if(!generate_dsa_primes(rng, p, q, pbits, qbits, seed)) {
383 throw Invalid_Argument("DL_Group: The seed given does not generate a DSA group");
384 }
385
386 const BigInt g = make_dsa_generator(p, q);
387
388 m_data = DL_Group_Data::create(p, q, g, DL_Group_Source::RandomlyGenerated);
389}
390
391/*
392* DL_Group Constructor
393*/
394DL_Group::DL_Group(const BigInt& p, const BigInt& g) {
395 m_data = DL_Group_Data::create(p, g, DL_Group_Source::ExternalSource);
396}
397
398/*
399* DL_Group Constructor
400*/
401DL_Group::DL_Group(const BigInt& p, const BigInt& q, const BigInt& g) {
402 if(q.is_zero()) {
403 m_data = DL_Group_Data::create(p, g, DL_Group_Source::ExternalSource);
404 } else {
405 m_data = DL_Group_Data::create(p, q, g, DL_Group_Source::ExternalSource);
406 }
407}
408
409const DL_Group_Data& DL_Group::data() const {
410 if(m_data) {
411 return *m_data;
412 }
413
414 throw Invalid_State("DL_Group uninitialized");
415}
416
418 const BigInt& p = get_p();
419 const BigInt& q = get_q();
420
421 if(y <= 1 || y >= p) {
422 return false;
423 }
424
425 if(!q.is_zero()) {
426 if(data().power_b_p_vartime(y, q) != 1) {
427 return false;
428 }
429 }
430
431 return true;
432}
433
435 const BigInt& p = get_p();
436 const BigInt& q = get_q();
437
438 if(x <= 1 || x >= p) {
439 return false;
440 }
441
442 if(q > 0 && x > q) {
443 return false;
444 }
445
446 return true;
447}
448
449bool DL_Group::verify_element_pair(const BigInt& y, const BigInt& x) const {
450 const BigInt& p = get_p();
451
452 if(y <= 1 || y >= p || x <= 1 || x >= p) {
453 return false;
454 }
455
456 if(y != this->power_g_p(x, x.bits())) {
457 return false;
458 }
459
460 return true;
461}
462
463/*
464* Verify the parameters
465*/
466bool DL_Group::verify_group(RandomNumberGenerator& rng, bool strong) const {
467 const bool from_builtin = (source() == DL_Group_Source::Builtin);
468
469 if(!strong && from_builtin) {
470 return true;
471 }
472
473 const BigInt& p = get_p();
474 const BigInt& q = get_q();
475 const BigInt& g = get_g();
476
477 if(g < 2 || p < 3 || q < 0) {
478 return false;
479 }
480
481 const size_t test_prob = 128;
482 const bool is_randomly_generated = (source() != DL_Group_Source::ExternalSource);
483
484 if(!is_prime(p, rng, test_prob, is_randomly_generated)) {
485 return false;
486 }
487
488 if(q != 0) {
489 if((p - 1) % q != 0) {
490 return false;
491 }
492 if(data().power_g_p_vartime(q) != 1) {
493 return false;
494 }
495 if(!is_prime(q, rng, test_prob, is_randomly_generated)) {
496 return false;
497 }
498 } else {
499 if(!from_builtin && !is_randomly_generated) {
500 // If we got this p,g from some unknown source, try to verify
501 // that the group order is not too absurdly small.
502
503 const size_t upper_bound = strong ? 1000 : 100;
504
505 for(size_t i = 2; i != upper_bound; ++i) {
506 if(data().power_g_p_vartime(BigInt::from_word(i)) == 1) {
507 return false;
508 }
509 }
510 }
511 }
512
513 return true;
514}
515
516/*
517* Return the prime
518*/
519const BigInt& DL_Group::get_p() const {
520 return data().p();
521}
522
523/*
524* Return the generator
525*/
526const BigInt& DL_Group::get_g() const {
527 return data().g();
528}
529
530/*
531* Return the subgroup
532*/
533const BigInt& DL_Group::get_q() const {
534 return data().q();
535}
536
538 return data().monty_params_p();
539}
540
541bool DL_Group::has_q() const {
542 return data().q_is_set();
543}
544
545size_t DL_Group::p_bits() const {
546 return data().p_bits();
547}
548
549size_t DL_Group::p_bytes() const {
550 return data().p_bytes();
551}
552
553size_t DL_Group::q_bits() const {
554 data().assert_q_is_set("q_bits");
555 return data().q_bits();
556}
557
558size_t DL_Group::q_bytes() const {
559 data().assert_q_is_set("q_bytes");
560 return data().q_bytes();
561}
562
564 return data().estimated_strength();
565}
566
568 return data().exponent_bits();
569}
570
572 // precompute??
573 return inverse_mod_public_prime(x, get_p());
574}
575
577 return data().reducer_mod_p().reduce(x);
578}
579
580BigInt DL_Group::multiply_mod_p(const BigInt& x, const BigInt& y) const {
581 return data().reducer_mod_p().multiply(x, y);
582}
583
585 return data().reducer_mod_p();
586}
587
589 data().assert_q_is_set("inverse_mod_q");
590 // precompute??
591 return inverse_mod_public_prime(x, get_q());
592}
593
595 data().assert_q_is_set("mod_q");
596 return data().reducer_mod_q().reduce(x);
597}
598
599BigInt DL_Group::multiply_mod_q(const BigInt& x, const BigInt& y) const {
600 data().assert_q_is_set("multiply_mod_q");
601 return data().reducer_mod_q().multiply(x, y);
602}
603
604BigInt DL_Group::multiply_mod_q(const BigInt& x, const BigInt& y, const BigInt& z) const {
605 data().assert_q_is_set("multiply_mod_q");
606 return this->multiply_mod_q(this->multiply_mod_q(x, y), z);
607}
608
610 data().assert_q_is_set("square_mod_q");
611 return data().reducer_mod_q().square(x);
612}
613
614BigInt DL_Group::multi_exponentiate(const BigInt& x, const BigInt& y, const BigInt& z) const {
615 return monty_multi_exp(data().monty_params_p(), get_g(), x, y, z).value();
616}
617
618BigInt DL_Group::power_g_p(const BigInt& x, size_t max_x_bits) const {
619 return data().power_g_p(x, max_x_bits);
620}
621
622BigInt DL_Group::power_b_p(const BigInt& b, const BigInt& x) const {
623 return this->power_b_p(b, x, data().p_bits());
624}
625
626BigInt DL_Group::power_b_p(const BigInt& b, const BigInt& x, size_t max_x_bits) const {
627 return data().power_b_p(b, x, max_x_bits);
628}
629
631 return data().source();
632}
633
634/*
635* DER encode the parameters
636*/
637std::vector<uint8_t> DL_Group::DER_encode(DL_Group_Format format) const {
638 if(get_q().is_zero() && (format != DL_Group_Format::PKCS_3)) {
639 throw Encoding_Error("Cannot encode DL_Group in ANSI formats when q param is missing");
640 }
641
642 std::vector<uint8_t> output;
643 DER_Encoder der(output);
644
645 if(format == DL_Group_Format::ANSI_X9_57) {
647 } else if(format == DL_Group_Format::ANSI_X9_42) {
649 } else if(format == DL_Group_Format::PKCS_3) {
651 } else {
652 throw Invalid_Argument("Unknown DL_Group encoding");
653 }
654
655 return output;
656}
657
658/*
659* PEM encode the parameters
660*/
661std::string DL_Group::PEM_encode(DL_Group_Format format) const {
662 const std::vector<uint8_t> encoding = DER_encode(format);
663
664 if(format == DL_Group_Format::PKCS_3) {
665 return PEM_Code::encode(encoding, "DH PARAMETERS");
666 } else if(format == DL_Group_Format::ANSI_X9_57) {
667 return PEM_Code::encode(encoding, "DSA PARAMETERS");
668 } else if(format == DL_Group_Format::ANSI_X9_42) {
669 return PEM_Code::encode(encoding, "X9.42 DH PARAMETERS");
670 } else {
671 throw Invalid_Argument("Unknown DL_Group encoding");
672 }
673}
674
675DL_Group::DL_Group(std::span<const uint8_t> der, DL_Group_Format format) {
676 m_data = DER_decode_DL_group(der, format, DL_Group_Source::ExternalSource);
677}
678
679} // namespace Botan
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
static Limits DER()
Definition ber_dec.h:35
static Barrett_Reduction for_public_modulus(const BigInt &m)
Definition barrett.cpp:33
void randomize(RandomNumberGenerator &rng, size_t bitsize, bool set_high_bit=true)
Definition big_rand.cpp:19
size_t bits() const
Definition bigint.cpp:307
static BigInt from_word(word n)
Definition bigint.cpp:35
bool is_zero() const
Definition bigint.h:484
BigInt & square(secure_vector< word > &ws)
Definition big_ops2.cpp:175
DER_Encoder & start_sequence()
Definition der_enc.h:67
DER_Encoder & end_cons()
Definition der_enc.cpp:173
DER_Encoder & encode(bool b)
Definition der_enc.cpp:245
const Barrett_Reduction & _reducer_mod_p() const
Definition dl_group.cpp:584
bool verify_private_element(const BigInt &x) const
Definition dl_group.cpp:434
std::vector< uint8_t > DER_encode(DL_Group_Format format) const
Definition dl_group.cpp:637
BigInt power_g_p(const BigInt &x) const
Definition dl_group.h:261
static DL_Group from_PEM(std::string_view pem)
Definition dl_group.cpp:273
BigInt mod_p(const BigInt &x) const
Definition dl_group.cpp:576
BigInt multiply_mod_p(const BigInt &x, const BigInt &y) const
Definition dl_group.cpp:580
size_t p_bits() const
Definition dl_group.cpp:545
std::string PEM_encode(DL_Group_Format format) const
Definition dl_group.cpp:661
const BigInt & get_p() const
Definition dl_group.cpp:519
static DL_Group from_name(std::string_view name)
Definition dl_group.cpp:262
BigInt multi_exponentiate(const BigInt &x, const BigInt &y, const BigInt &z) const
Definition dl_group.cpp:614
bool verify_public_element(const BigInt &y) const
Definition dl_group.cpp:417
BigInt square_mod_q(const BigInt &x) const
Definition dl_group.cpp:609
BigInt inverse_mod_q(const BigInt &x) const
Definition dl_group.cpp:588
size_t p_bytes() const
Definition dl_group.cpp:549
bool verify_element_pair(const BigInt &y, const BigInt &x) const
Definition dl_group.cpp:449
size_t estimated_strength() const
Definition dl_group.cpp:563
size_t q_bytes() const
Definition dl_group.cpp:558
bool has_q() const
Definition dl_group.cpp:541
DL_Group_Source source() const
Definition dl_group.cpp:630
BigInt multiply_mod_q(const BigInt &x, const BigInt &y) const
Definition dl_group.cpp:599
BigInt inverse_mod_p(const BigInt &x) const
Definition dl_group.cpp:571
size_t q_bits() const
Definition dl_group.cpp:553
DL_Group()=default
const Montgomery_Params & _monty_params_p() const
Definition dl_group.cpp:537
BigInt power_b_p(const BigInt &b, const BigInt &x, size_t max_x_bits) const
Definition dl_group.cpp:626
size_t exponent_bits() const
Definition dl_group.cpp:567
BigInt mod_q(const BigInt &x) const
Definition dl_group.cpp:594
bool verify_group(RandomNumberGenerator &rng, bool strong=true) const
Definition dl_group.cpp:466
const BigInt & get_g() const
Definition dl_group.cpp:526
static std::shared_ptr< DL_Group_Data > DL_group_info(std::string_view name)
Definition dl_named.cpp:13
const BigInt & get_q() const
Definition dl_group.cpp:533
BigInt value() const
Definition monty.cpp:246
std::string encode(const uint8_t der[], size_t length, std::string_view label, size_t width)
Definition pem.cpp:39
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
Definition pem.cpp:62
void vartime_divide(const BigInt &x, const BigInt &y_arg, BigInt &q_out, BigInt &r_out)
Definition divide.cpp:325
int32_t jacobi(BigInt a, BigInt n)
Definition numthry.cpp:119
BigInt random_prime(RandomNumberGenerator &rng, size_t bits, const BigInt &coprime, size_t equiv, size_t modulo, size_t prob)
Definition make_prm.cpp:112
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
Montgomery_Int monty_exp_vartime(const Montgomery_Params &params_p, const BigInt &g, const BigInt &k)
Definition monty_exp.h:54
size_t dl_exponent_size(size_t p_bits)
std::shared_ptr< const Montgomery_Exponentiation_State > monty_precompute(const Montgomery_Int &g, size_t window_bits, bool const_time)
const uint16_t PRIMES[]
Definition primes.cpp:12
const size_t PRIME_TABLE_SIZE
Definition numthry.h:175
size_t dl_work_factor(size_t bits)
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
Definition numthry.cpp:381
BigInt inverse_mod_public_prime(const BigInt &x, const BigInt &p)
Definition mod_inv.cpp:294
Montgomery_Int monty_multi_exp(const Montgomery_Params &params_p, const BigInt &x_bn, const BigInt &z1, const BigInt &y_bn, const BigInt &z2)
Montgomery_Int monty_execute_vartime(const Montgomery_Exponentiation_State &precomputed_state, const BigInt &k)
std::vector< T > unlock(const secure_vector< T > &in)
Definition secmem.h:85
bool generate_dsa_primes(RandomNumberGenerator &rng, BigInt &p, BigInt &q, size_t pbits, size_t qbits, const std::vector< uint8_t > &seed_c, size_t offset)
Definition dsa_gen.cpp:54
Montgomery_Int monty_execute(const Montgomery_Exponentiation_State &precomputed_state, const BigInt &k, size_t max_k_bits)
DL_Group_Format
Definition dl_group.h:30
DL_Group_Source
Definition dl_group.h:21
BigInt random_safe_prime(RandomNumberGenerator &rng, size_t bits)
Definition make_prm.cpp:314
Montgomery_Int monty_exp(const Montgomery_Params &params_p, const BigInt &g, const BigInt &k, size_t max_k_bits)
Definition monty_exp.h:46