From 3009920d500adada75f8e9dd7b28eeca3c42354f Mon Sep 17 00:00:00 2001 From: lloyd Date: Thu, 1 Mar 2007 00:14:46 +0000 Subject: Split DSA parameter generation into src/dsa_gen.cpp, and make the functions members of DL_Group (the only place they were called within the source, and outside of some rather esoteric things probably the only place you would ever need it). --- src/dsa_gen.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/make_prm.cpp | 97 +----------------------------------------------- 2 files changed, 112 insertions(+), 96 deletions(-) create mode 100644 src/dsa_gen.cpp (limited to 'src') diff --git a/src/dsa_gen.cpp b/src/dsa_gen.cpp new file mode 100644 index 000000000..996cb550e --- /dev/null +++ b/src/dsa_gen.cpp @@ -0,0 +1,111 @@ +/************************************************* +* DSA Parameter Generation Source File * +* (C) 1999-2007 The Botan Project * +*************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +/************************************************* +* Increment the seed by one * +*************************************************/ +void increment(SecureVector& seed) + { + for(u32bit j = seed.size(); j > 0; --j) + if(++seed[j-1]) + break; + } + +} + +/************************************************* +* Attempt DSA prime generation with given seed * +*************************************************/ +bool DL_Group::generate_dsa_primes(BigInt& p, BigInt& q, + const byte const_seed[], u32bit seed_len, + u32bit pbits, u32bit counter_start) + { + if(seed_len < 20) + throw Invalid_Argument("DSA prime generation needs a seed " + "at least 160 bits long"); + if((pbits % 64 != 0) || (pbits > 1024) || (pbits < 512)) + throw Invalid_Argument("DSA prime generation algorithm does not support " + "prime size " + to_string(pbits)); + + std::auto_ptr sha1(get_hash("SHA-1")); + + SecureVector seed(const_seed, seed_len); + + SecureVector qhash = sha1->process(seed); + increment(seed); + SecureVector qhash2 = sha1->process(seed); + xor_buf(qhash, qhash2, qhash.size()); + + qhash[0] |= 0x80; + qhash[19] |= 0x01; + q.binary_decode(qhash, qhash.size()); + if(!is_prime(q)) + return false; + global_state().pulse(PRIME_FOUND); + + u32bit n = (pbits-1) / 160, b = (pbits-1) % 160; + SecureVector W(20 * (n+1)); + BigInt X; + + for(u32bit j = 0; j != counter_start; ++j) + for(u32bit k = 0; k != n + 1; ++k) + increment(seed); + + for(u32bit j = 0; j != 4096 - counter_start; ++j) + { + global_state().pulse(PRIME_SEARCHING); + + for(u32bit k = 0; k != n + 1; ++k) + { + increment(seed); + sha1->update(seed); + sha1->final(W + 20 * (n-k)); + } + X.binary_decode(W + (20 - 1 - b/8), W.size() - (20 - 1 - b/8)); + X.set_bit(pbits-1); + + p = X - (X % (2*q) - 1); + + if(p.bits() == pbits && is_prime(p)) + { + global_state().pulse(PRIME_FOUND); + return true; + } + } + return false; + } + +/************************************************* +* Generate DSA Primes * +*************************************************/ +SecureVector DL_Group::generate_dsa_primes(BigInt& p, BigInt& q, + u32bit pbits) + { + SecureVector seed(20); + + while(true) + { + Global_RNG::randomize(seed, seed.size()); + global_state().pulse(PRIME_SEARCHING); + if(generate_dsa_primes(p, q, seed, seed.size(), pbits, 0)) + return seed; + } + } + +} diff --git a/src/make_prm.cpp b/src/make_prm.cpp index bf7188345..a3258c131 100644 --- a/src/make_prm.cpp +++ b/src/make_prm.cpp @@ -4,107 +4,12 @@ *************************************************/ #include -#include -#include -#include #include -#include +#include #include -#include namespace Botan { -namespace { - -/************************************************* -* Increment the seed by one * -*************************************************/ -void increment(SecureVector& seed) - { - for(u32bit j = seed.size(); j > 0; --j) - if(++seed[j-1]) - break; - } - -} - -/************************************************* -* Attempt DSA prime generation with given seed * -*************************************************/ -bool generate_dsa_primes(BigInt& p, BigInt& q, const byte const_seed[], - u32bit seed_len, u32bit pbits, u32bit counter_start) - { - if(seed_len < 20) - throw Invalid_Argument("DSA prime generation needs a seed " - "at least 160 bits long"); - if((pbits % 64 != 0) || (pbits > 1024) || (pbits < 512)) - throw Invalid_Argument("DSA prime generation algorithm does not support " - "prime size " + to_string(pbits)); - - std::auto_ptr sha1(get_hash("SHA-1")); - - SecureVector seed(const_seed, seed_len); - - SecureVector qhash = sha1->process(seed); - increment(seed); - SecureVector qhash2 = sha1->process(seed); - xor_buf(qhash, qhash2, qhash.size()); - - qhash[0] |= 0x80; - qhash[19] |= 0x01; - q.binary_decode(qhash, qhash.size()); - if(!is_prime(q)) - return false; - global_state().pulse(PRIME_FOUND); - - u32bit n = (pbits-1) / 160, b = (pbits-1) % 160; - SecureVector W(20 * (n+1)); - BigInt X; - - for(u32bit j = 0; j != counter_start; ++j) - for(u32bit k = 0; k != n + 1; ++k) - increment(seed); - - for(u32bit j = 0; j != 4096 - counter_start; ++j) - { - global_state().pulse(PRIME_SEARCHING); - - for(u32bit k = 0; k != n + 1; ++k) - { - increment(seed); - sha1->update(seed); - sha1->final(W + 20 * (n-k)); - } - X.binary_decode(W + (20 - 1 - b/8), W.size() - (20 - 1 - b/8)); - X.set_bit(pbits-1); - - p = X - (X % (2*q) - 1); - - if(p.bits() == pbits && is_prime(p)) - { - global_state().pulse(PRIME_FOUND); - return true; - } - } - return false; - } - -/************************************************* -* Generate DSA Primes * -*************************************************/ -SecureVector generate_dsa_primes(BigInt& p, BigInt& q, u32bit pbits) - { - SecureVector seed(20); - - while(true) - { - Global_RNG::randomize(seed, seed.size()); - global_state().pulse(PRIME_SEARCHING); - if(generate_dsa_primes(p, q, seed, seed.size(), pbits)) - return seed; - } - } - /************************************************* * Generate a random prime * *************************************************/ -- cgit v1.2.3