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