From c32a8e6c7ecf97fc9423e6a967ce3d98b0689404 Mon Sep 17 00:00:00 2001 From: lloyd Date: Sun, 28 Sep 2008 22:40:27 +0000 Subject: Move all BigInt stuff into bigint/. Currently all asm modules are disabled; configure.pl doesn't understand how to handle this yet (replace logic only understands stuff in src, not how one module can replace another modules src, or anything about prioritizing). Move some hex and base64 stuff out of charset.cpp and into their codec directories. --- src/bigint/dsa_gen.cpp | 134 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 src/bigint/dsa_gen.cpp (limited to 'src/bigint/dsa_gen.cpp') diff --git a/src/bigint/dsa_gen.cpp b/src/bigint/dsa_gen.cpp new file mode 100644 index 000000000..baaba66ee --- /dev/null +++ b/src/bigint/dsa_gen.cpp @@ -0,0 +1,134 @@ +/************************************************* +* DSA Parameter Generation Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +/************************************************* +* Check if this size is allowed by FIPS 186-3 * +*************************************************/ +bool fips186_3_valid_size(u32bit pbits, u32bit qbits) + { + if(qbits == 160) + return (pbits == 512 || pbits == 768 || pbits == 1024); + + if(qbits == 224) + return (pbits == 2048); + + if(qbits == 256) + return (pbits == 2048 || pbits == 3072); + + return false; + } + +} + +/************************************************* +* Attempt DSA prime generation with given seed * +*************************************************/ +bool DL_Group::generate_dsa_primes(RandomNumberGenerator& rng, + BigInt& p, BigInt& q, + u32bit pbits, u32bit qbits, + const MemoryRegion& seed_c) + { + if(!fips186_3_valid_size(pbits, qbits)) + throw Invalid_Argument( + "FIPS 186-3 does not allow DSA domain parameters of " + + to_string(pbits) + "/" + to_string(qbits) + " bits long"); + + if(qbits == 224) + throw Invalid_Argument( + "DSA parameter generation with a q of 224 bits not supported"); + + if(seed_c.size() * 8 < qbits) + throw Invalid_Argument( + "Generating a DSA parameter set with a " + to_string(qbits) + + "long q requires a seed at least as many bits long"); + + std::auto_ptr hash(get_hash("SHA-" + to_string(qbits))); + + const u32bit HASH_SIZE = hash->OUTPUT_LENGTH; + + class Seed + { + public: + Seed(const MemoryRegion& s) : seed(s) {} + + operator MemoryRegion& () { return seed; } + + Seed& operator++() + { + for(u32bit j = seed.size(); j > 0; --j) + if(++seed[j-1]) + break; + return (*this); + } + private: + SecureVector seed; + }; + + Seed seed(seed_c); + + q.binary_decode(hash->process(seed)); + q.set_bit(qbits-1); + q.set_bit(0); + + if(!is_prime(q, rng)) + return false; + + const u32bit n = (pbits-1) / (HASH_SIZE * 8), + b = (pbits-1) % (HASH_SIZE * 8); + + BigInt X; + SecureVector V(HASH_SIZE * (n+1)); + + for(u32bit j = 0; j != 4096; ++j) + { + for(u32bit k = 0; k <= n; ++k) + { + ++seed; + hash->update(seed); + hash->final(V + HASH_SIZE * (n-k)); + } + + X.binary_decode(V + (HASH_SIZE - 1 - b/8), + V.size() - (HASH_SIZE - 1 - b/8)); + X.set_bit(pbits-1); + + p = X - (X % (2*q) - 1); + + if(p.bits() == pbits && is_prime(p, rng)) + return true; + } + return false; + } + +/************************************************* +* Generate DSA Primes * +*************************************************/ +SecureVector DL_Group::generate_dsa_primes(RandomNumberGenerator& rng, + BigInt& p, BigInt& q, + u32bit pbits, u32bit qbits) + { + SecureVector seed(qbits/8); + + while(true) + { + rng.randomize(seed, seed.size()); + + if(generate_dsa_primes(rng, p, q, pbits, qbits, seed)) + return seed; + } + } + +} -- cgit v1.2.3