diff options
-rw-r--r-- | include/dl_group.h | 7 | ||||
-rw-r--r-- | include/numthry.h | 4 | ||||
-rw-r--r-- | src/dsa_gen.cpp | 111 | ||||
-rw-r--r-- | src/make_prm.cpp | 97 |
4 files changed, 117 insertions, 102 deletions
diff --git a/include/dl_group.h b/include/dl_group.h index 6a1ff4c81..6cd46c1c4 100644 --- a/include/dl_group.h +++ b/include/dl_group.h @@ -31,8 +31,6 @@ class DL_Group void BER_decode(DataSource&, Format); void PEM_decode(DataSource&); - static BigInt make_dsa_generator(const BigInt&, const BigInt&); - DL_Group(); DL_Group(const std::string&); DL_Group(u32bit, PrimeType = Strong); @@ -40,6 +38,11 @@ class DL_Group DL_Group(const BigInt&, const BigInt&); DL_Group(const BigInt&, const BigInt&, const BigInt&); private: + static BigInt make_dsa_generator(const BigInt&, const BigInt&); + static SecureVector<byte> generate_dsa_primes(BigInt&, BigInt&, u32bit); + static bool generate_dsa_primes(BigInt&, BigInt&, const byte[], u32bit, + u32bit, u32bit = 0); + void init_check() const; void initialize(const BigInt&, const BigInt&, const BigInt&); bool initialized; diff --git a/include/numthry.h b/include/numthry.h index 8ec0d58f9..abb423e52 100644 --- a/include/numthry.h +++ b/include/numthry.h @@ -58,10 +58,6 @@ BigInt random_integer(const BigInt&, const BigInt&); BigInt random_prime(u32bit, const BigInt& = 1, u32bit = 1, u32bit = 2); BigInt random_safe_prime(u32bit); -SecureVector<byte> generate_dsa_primes(BigInt&, BigInt&, u32bit); -bool generate_dsa_primes(BigInt&, BigInt&, const byte[], u32bit, u32bit, - u32bit = 0); - /************************************************* * Prime Numbers * *************************************************/ 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 <botan/dl_group.h> +#include <botan/numthry.h> +#include <botan/libstate.h> +#include <botan/lookup.h> +#include <botan/bit_ops.h> +#include <botan/parsing.h> +#include <botan/rng.h> +#include <algorithm> +#include <memory> + +namespace Botan { + +namespace { + +/************************************************* +* Increment the seed by one * +*************************************************/ +void increment(SecureVector<byte>& 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<HashFunction> sha1(get_hash("SHA-1")); + + SecureVector<byte> seed(const_seed, seed_len); + + SecureVector<byte> qhash = sha1->process(seed); + increment(seed); + SecureVector<byte> 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<byte> 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<byte> DL_Group::generate_dsa_primes(BigInt& p, BigInt& q, + u32bit pbits) + { + SecureVector<byte> 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 <botan/numthry.h> -#include <botan/libstate.h> -#include <botan/lookup.h> -#include <botan/bit_ops.h> #include <botan/parsing.h> -#include <botan/rng.h> +#include <botan/libstate.h> #include <algorithm> -#include <memory> namespace Botan { -namespace { - -/************************************************* -* Increment the seed by one * -*************************************************/ -void increment(SecureVector<byte>& 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<HashFunction> sha1(get_hash("SHA-1")); - - SecureVector<byte> seed(const_seed, seed_len); - - SecureVector<byte> qhash = sha1->process(seed); - increment(seed); - SecureVector<byte> 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<byte> 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<byte> generate_dsa_primes(BigInt& p, BigInt& q, u32bit pbits) - { - SecureVector<byte> 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 * *************************************************/ |