diff options
author | lloyd <[email protected]> | 2008-05-24 18:25:00 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2008-05-24 18:25:00 +0000 |
commit | b7563677f13adb8dfa5813ef91ed79364b2d984d (patch) | |
tree | cf7fabb3eb43bc49333be726c15ecac1a7f9a1a7 /src | |
parent | a6a9110d02925e111cff2dc1143a09a3b7680f0b (diff) |
Previously random_integer and friends used the global PRNG object to get
random bits. Now they take a reference to a RandomNumberGenerator object.
This was applied several times out, so now the constructors to private
key objects also take a RandomNumberGenerator& argument. This is also true
for a number of randomized algorithms (Miller-Rabin, for instance).
You can get a reference to the global PRNG with
global_state().prng_reference()
This is a provisional thing: and warning: it is not thread safe! If this
is a problem instead keep per-thread PRNGs and pass them were needed.
Diffstat (limited to 'src')
-rw-r--r-- | src/big_rand.cpp | 27 | ||||
-rw-r--r-- | src/dh.cpp | 5 | ||||
-rw-r--r-- | src/dl_algo.cpp | 5 | ||||
-rw-r--r-- | src/dl_group.cpp | 25 | ||||
-rw-r--r-- | src/dsa.cpp | 10 | ||||
-rw-r--r-- | src/dsa_gen.cpp | 10 | ||||
-rw-r--r-- | src/elgamal.cpp | 11 | ||||
-rw-r--r-- | src/if_algo.cpp | 4 | ||||
-rw-r--r-- | src/make_prm.cpp | 8 | ||||
-rw-r--r-- | src/nr.cpp | 8 | ||||
-rw-r--r-- | src/numthry.cpp | 22 | ||||
-rw-r--r-- | src/pk_core.cpp | 10 | ||||
-rw-r--r-- | src/rsa.cpp | 8 | ||||
-rw-r--r-- | src/rw.cpp | 10 | ||||
-rw-r--r-- | src/x509_ca.cpp | 6 |
15 files changed, 101 insertions, 68 deletions
diff --git a/src/big_rand.cpp b/src/big_rand.cpp index 264f5dcb3..5e6ec594b 100644 --- a/src/big_rand.cpp +++ b/src/big_rand.cpp @@ -6,7 +6,6 @@ #include <botan/bigint.h> #include <botan/parsing.h> #include <botan/numthry.h> -#include <botan/libstate.h> namespace Botan { @@ -16,9 +15,8 @@ namespace Botan { BigInt::BigInt(NumberType type, u32bit bits) { set_sign(Positive); - if(type == Random && bits) - randomize(bits); - else if(type == Power2) + + if(type == Power2) set_bit(bits); else throw Invalid_Argument("BigInt(NumberType): Unknown type"); @@ -27,7 +25,8 @@ BigInt::BigInt(NumberType type, u32bit bits) /************************************************* * Randomize this number * *************************************************/ -void BigInt::randomize(u32bit bitsize) +void BigInt::randomize(RandomNumberGenerator& rng, + u32bit bitsize) { set_sign(Positive); @@ -36,7 +35,7 @@ void BigInt::randomize(u32bit bitsize) else { SecureVector<byte> array((bitsize + 7) / 8); - global_state().randomize(array, array.size()); + rng.randomize(array, array.size()); if(bitsize % 8) array[0] &= 0xFF >> (8 - (bitsize % 8)); array[0] |= 0x80 >> ((bitsize % 8) ? (8 - bitsize % 8) : 0); @@ -47,30 +46,32 @@ void BigInt::randomize(u32bit bitsize) /************************************************* * Generate a random integer * *************************************************/ -BigInt random_integer(u32bit bits) +BigInt random_integer(RandomNumberGenerator& rng, + u32bit bits) { BigInt x; - x.randomize(bits); + x.randomize(rng, bits); return x; } /************************************************* * Generate a random integer within given range * *************************************************/ -BigInt random_integer(const BigInt& min, const BigInt& max) +BigInt random_integer(RandomNumberGenerator& rng, + const BigInt& min, const BigInt& max) { BigInt range = max - min; if(range <= 0) throw Invalid_Argument("random_integer: invalid min/max values"); - return (min + (random_integer(range.bits() + 2) % range)); + return (min + (random_integer(rng, range.bits() + 2) % range)); } /************************************************* * Generate a random safe prime * *************************************************/ -BigInt random_safe_prime(u32bit bits) +BigInt random_safe_prime(RandomNumberGenerator& rng, u32bit bits) { if(bits <= 64) throw Invalid_Argument("random_safe_prime: Can't make a prime of " + @@ -78,8 +79,8 @@ BigInt random_safe_prime(u32bit bits) BigInt p; do - p = (random_prime(bits - 1) << 1) + 1; - while(!is_prime(p)); + p = (random_prime(rng, bits - 1) << 1) + 1; + while(!is_prime(p, rng)); return p; } diff --git a/src/dh.cpp b/src/dh.cpp index e78bf802e..bf5ad5b11 100644 --- a/src/dh.cpp +++ b/src/dh.cpp @@ -46,12 +46,13 @@ MemoryVector<byte> DH_PublicKey::public_value() const /************************************************* * Create a DH private key * *************************************************/ -DH_PrivateKey::DH_PrivateKey(const DL_Group& grp) +DH_PrivateKey::DH_PrivateKey(const DL_Group& grp, + RandomNumberGenerator& rng) { group = grp; const BigInt& p = group_p(); - x = random_integer(2 * dl_work_factor(p.bits())); + x = random_integer(rng, 2 * dl_work_factor(p.bits())); PKCS8_load_hook(true); } diff --git a/src/dl_algo.cpp b/src/dl_algo.cpp index 8654122e3..afefe2df3 100644 --- a/src/dl_algo.cpp +++ b/src/dl_algo.cpp @@ -7,6 +7,7 @@ #include <botan/numthry.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> +#include <botan/libstate.h> namespace Botan { @@ -131,7 +132,7 @@ bool DL_Scheme_PublicKey::check_key(bool strong) const { if(y < 2 || y >= group_p()) return false; - if(!group.verify_group(strong)) + if(!group.verify_group(global_state().prng_reference(), strong)) return false; return true; } @@ -146,7 +147,7 @@ bool DL_Scheme_PrivateKey::check_key(bool strong) const if(y < 2 || y >= p || x < 2 || x >= p) return false; - if(!group.verify_group(strong)) + if(!group.verify_group(global_state().prng_reference(), strong)) return false; if(!strong) diff --git a/src/dl_group.cpp b/src/dl_group.cpp index b356b707d..d0b27be0c 100644 --- a/src/dl_group.cpp +++ b/src/dl_group.cpp @@ -1,9 +1,10 @@ /************************************************* * Discrete Logarithm Parameters Source File * -* (C) 1999-2007 Jack Lloyd * +* (C) 1999-2008 Jack Lloyd * *************************************************/ #include <botan/dl_group.h> +#include <botan/libstate.h> #include <botan/config.h> #include <botan/parsing.h> #include <botan/numthry.h> @@ -40,7 +41,8 @@ DL_Group::DL_Group(const std::string& type) /************************************************* * DL_Group Constructor * *************************************************/ -DL_Group::DL_Group(PrimeType type, u32bit pbits, u32bit qbits) +DL_Group::DL_Group(RandomNumberGenerator& rng, + PrimeType type, u32bit pbits, u32bit qbits) { if(pbits < 512) throw Invalid_Argument("DL_Group: prime size " + to_string(pbits) + @@ -48,7 +50,7 @@ DL_Group::DL_Group(PrimeType type, u32bit pbits, u32bit qbits) if(type == Strong) { - p = random_safe_prime(pbits); + p = random_safe_prime(rng, pbits); q = (p - 1) / 2; g = 2; } @@ -59,18 +61,18 @@ DL_Group::DL_Group(PrimeType type, u32bit pbits, u32bit qbits) if(!qbits) qbits = 2 * dl_work_factor(pbits); - q = random_prime(qbits); + q = random_prime(rng, qbits); BigInt X; - while(p.bits() != pbits || !is_prime(p)) + while(p.bits() != pbits || !is_prime(p, rng)) { - X = random_integer(pbits); + X = random_integer(rng, pbits); p = X - (X % (2*q) - 1); } } else { qbits = qbits ? qbits : ((pbits == 1024) ? 160 : 256); - generate_dsa_primes(p, q, pbits, qbits); + generate_dsa_primes(rng, p, q, pbits, qbits); } g = make_dsa_generator(p, q); @@ -125,7 +127,7 @@ void DL_Group::initialize(const BigInt& p1, const BigInt& q1, const BigInt& g1) g = g1; q = q1; - if(q == 0 && check_prime((p - 1) / 2)) + if(q == 0 && check_prime((p - 1) / 2, global_state().prng_reference())) q = (p - 1) / 2; initialized = true; @@ -143,7 +145,8 @@ void DL_Group::init_check() const /************************************************* * Verify the parameters * *************************************************/ -bool DL_Group::verify_group(bool strong) const +bool DL_Group::verify_group(RandomNumberGenerator& rng, + bool strong) const { init_check(); @@ -155,9 +158,9 @@ bool DL_Group::verify_group(bool strong) const if(!strong) return true; - if(!check_prime(p)) + if(!check_prime(p, rng)) return false; - if((q > 0) && !check_prime(q)) + if((q > 0) && !check_prime(q, rng)) return false; return true; } diff --git a/src/dsa.cpp b/src/dsa.cpp index 6030bc88a..13ab67374 100644 --- a/src/dsa.cpp +++ b/src/dsa.cpp @@ -1,11 +1,12 @@ /************************************************* * DSA Source File * -* (C) 1999-2007 Jack Lloyd * +* (C) 1999-2008 Jack Lloyd * *************************************************/ #include <botan/dsa.h> #include <botan/numthry.h> #include <botan/keypair.h> +#include <botan/libstate.h> namespace Botan { @@ -56,10 +57,11 @@ u32bit DSA_PublicKey::message_part_size() const /************************************************* * Create a DSA private key * *************************************************/ -DSA_PrivateKey::DSA_PrivateKey(const DL_Group& grp) +DSA_PrivateKey::DSA_PrivateKey(const DL_Group& grp, + RandomNumberGenerator& rng) { group = grp; - x = random_integer(2, group_q() - 1); + x = random_integer(rng, 2, group_q() - 1); PKCS8_load_hook(true); } @@ -101,7 +103,7 @@ SecureVector<byte> DSA_PrivateKey::sign(const byte in[], u32bit length) const BigInt k; do - k.randomize(q.bits()); + k.randomize(global_state().prng_reference(), q.bits()); while(k >= q); return core.sign(in, length, k); diff --git a/src/dsa_gen.cpp b/src/dsa_gen.cpp index 002af7d96..0e4f5301f 100644 --- a/src/dsa_gen.cpp +++ b/src/dsa_gen.cpp @@ -80,7 +80,7 @@ bool DL_Group::generate_dsa_primes(BigInt& p, BigInt& q, q.set_bit(qbits-1); q.set_bit(0); - if(!is_prime(q)) + if(!is_prime(q, global_state().prng_reference())) return false; const u32bit n = (pbits-1) / (HASH_SIZE * 8), @@ -104,7 +104,8 @@ bool DL_Group::generate_dsa_primes(BigInt& p, BigInt& q, p = X - (X % (2*q) - 1); - if(p.bits() == pbits && is_prime(p)) + if(p.bits() == pbits && + is_prime(p, global_state().prng_reference())) return true; } return false; @@ -113,14 +114,15 @@ bool DL_Group::generate_dsa_primes(BigInt& p, BigInt& q, /************************************************* * Generate DSA Primes * *************************************************/ -SecureVector<byte> DL_Group::generate_dsa_primes(BigInt& p, BigInt& q, +SecureVector<byte> DL_Group::generate_dsa_primes(RandomNumberGenerator& rng, + BigInt& p, BigInt& q, u32bit pbits, u32bit qbits) { SecureVector<byte> seed(qbits/8); while(true) { - global_state().randomize(seed, seed.size()); + rng.randomize(seed, seed.size()); if(generate_dsa_primes(p, q, pbits, qbits, seed)) return seed; diff --git a/src/elgamal.cpp b/src/elgamal.cpp index 65fd22180..bcb8a6cc0 100644 --- a/src/elgamal.cpp +++ b/src/elgamal.cpp @@ -7,6 +7,7 @@ #include <botan/numthry.h> #include <botan/keypair.h> #include <botan/util.h> +#include <botan/libstate.h> namespace Botan { @@ -35,7 +36,10 @@ void ElGamal_PublicKey::X509_load_hook() SecureVector<byte> ElGamal_PublicKey::encrypt(const byte in[], u32bit length) const { - BigInt k = random_integer(2 * dl_work_factor(group_p().bits())); + BigInt k = random_integer( + global_state().prng_reference(), + 2 * dl_work_factor(group_p().bits())); + return core.encrypt(in, length, k); } @@ -50,11 +54,12 @@ u32bit ElGamal_PublicKey::max_input_bits() const /************************************************* * ElGamal_PrivateKey Constructor * *************************************************/ -ElGamal_PrivateKey::ElGamal_PrivateKey(const DL_Group& grp) +ElGamal_PrivateKey::ElGamal_PrivateKey(const DL_Group& grp, + RandomNumberGenerator& rng) { group = grp; - x = random_integer(2 * dl_work_factor(group_p().bits())); + x = random_integer(rng, 2 * dl_work_factor(group_p().bits())); PKCS8_load_hook(true); } diff --git a/src/if_algo.cpp b/src/if_algo.cpp index 895e049d3..b8d8071f4 100644 --- a/src/if_algo.cpp +++ b/src/if_algo.cpp @@ -7,6 +7,7 @@ #include <botan/numthry.h> #include <botan/der_enc.h> #include <botan/ber_dec.h> +#include <botan/libstate.h> namespace Botan { @@ -202,7 +203,8 @@ bool IF_Scheme_PrivateKey::check_key(bool strong) const if(d1 != d % (p - 1) || d2 != d % (q - 1) || c != inverse_mod(q, p)) return false; - if(!check_prime(p) || !check_prime(q)) + if(!check_prime(p, global_state().prng_reference()) || + !check_prime(q, global_state().prng_reference())) return false; return true; } diff --git a/src/make_prm.cpp b/src/make_prm.cpp index d5f9961af..7d399b825 100644 --- a/src/make_prm.cpp +++ b/src/make_prm.cpp @@ -5,7 +5,6 @@ #include <botan/numthry.h> #include <botan/parsing.h> -#include <botan/libstate.h> #include <algorithm> namespace Botan { @@ -13,7 +12,8 @@ namespace Botan { /************************************************* * Generate a random prime * *************************************************/ -BigInt random_prime(u32bit bits, const BigInt& coprime, +BigInt random_prime(RandomNumberGenerator& rng, + u32bit bits, const BigInt& coprime, u32bit equiv, u32bit modulo) { if(bits < 48) @@ -29,7 +29,7 @@ BigInt random_prime(u32bit bits, const BigInt& coprime, while(true) { - BigInt p = random_integer(bits); + BigInt p = random_integer(rng, bits); p.set_bit(bits - 2); p.set_bit(0); @@ -61,7 +61,7 @@ BigInt random_prime(u32bit bits, const BigInt& coprime, if(!passes_sieve || gcd(p - 1, coprime) != 1) continue; - if(passes_mr_tests(p)) + if(passes_mr_tests(rng, p)) return p; } } diff --git a/src/nr.cpp b/src/nr.cpp index 80abbf508..0f911daac 100644 --- a/src/nr.cpp +++ b/src/nr.cpp @@ -6,6 +6,7 @@ #include <botan/nr.h> #include <botan/numthry.h> #include <botan/keypair.h> +#include <botan/libstate.h> namespace Botan { @@ -55,10 +56,11 @@ u32bit NR_PublicKey::message_part_size() const /************************************************* * Create a NR private key * *************************************************/ -NR_PrivateKey::NR_PrivateKey(const DL_Group& grp) +NR_PrivateKey::NR_PrivateKey(const DL_Group& grp, + RandomNumberGenerator& rng) { group = grp; - x = random_integer(2, group_q() - 1); + x = random_integer(rng, 2, group_q() - 1); PKCS8_load_hook(true); } @@ -100,7 +102,7 @@ SecureVector<byte> NR_PrivateKey::sign(const byte in[], u32bit length) const BigInt k; do - k.randomize(q.bits()); + k.randomize(global_state().prng_reference(), q.bits()); while(k >= q); return core.sign(in, length, k); diff --git a/src/numthry.cpp b/src/numthry.cpp index 01b46c982..f36e2f3fe 100644 --- a/src/numthry.cpp +++ b/src/numthry.cpp @@ -209,41 +209,43 @@ s32bit simple_primality_tests(const BigInt& n) /************************************************* * Fast check of primality * *************************************************/ -bool check_prime(const BigInt& n) +bool check_prime(const BigInt& n, RandomNumberGenerator& rng) { - return run_primality_tests(n, 0); + return run_primality_tests(rng, n, 0); } /************************************************* * Test for primality * *************************************************/ -bool is_prime(const BigInt& n) +bool is_prime(const BigInt& n, RandomNumberGenerator& rng) { - return run_primality_tests(n, 1); + return run_primality_tests(rng, n, 1); } /************************************************* * Verify primality * *************************************************/ -bool verify_prime(const BigInt& n) +bool verify_prime(const BigInt& n, RandomNumberGenerator& rng) { - return run_primality_tests(n, 2); + return run_primality_tests(rng, n, 2); } /************************************************* * Verify primality * *************************************************/ -bool run_primality_tests(const BigInt& n, u32bit level) +bool run_primality_tests(RandomNumberGenerator& rng, + const BigInt& n, u32bit level) { s32bit simple_tests = simple_primality_tests(n); if(simple_tests) return (simple_tests == 1) ? true : false; - return passes_mr_tests(n, level); + return passes_mr_tests(rng, n, level); } /************************************************* * Test for primaility using Miller-Rabin * *************************************************/ -bool passes_mr_tests(const BigInt& n, u32bit level) +bool passes_mr_tests(RandomNumberGenerator& rng, + const BigInt& n, u32bit level) { const u32bit PREF_NONCE_BITS = 40; @@ -267,7 +269,7 @@ bool passes_mr_tests(const BigInt& n, u32bit level) BigInt nonce; for(u32bit j = 0; j != tests; ++j) { - if(verify) nonce = random_integer(NONCE_BITS); + if(verify) nonce = random_integer(rng, NONCE_BITS); else nonce = PRIMES[j]; if(!mr.passes_test(nonce)) diff --git a/src/pk_core.cpp b/src/pk_core.cpp index 42abe7196..4c76716f2 100644 --- a/src/pk_core.cpp +++ b/src/pk_core.cpp @@ -8,6 +8,7 @@ #include <botan/engine.h> #include <botan/config.h> #include <botan/parsing.h> +#include <botan/libstate.h> #include <algorithm> namespace Botan { @@ -29,7 +30,8 @@ IF_Core::IF_Core(const BigInt& e, const BigInt& n, const BigInt& d, if(d != 0) { - BigInt k = random_integer(std::min(n.bits()-1, BLINDING_BITS)); + BigInt k = random_integer(global_state().prng_reference(), + std::min(n.bits()-1, BLINDING_BITS)); if(k != 0) blinder = Blinder(power_mod(k, e, n), inverse_mod(k, n), n); } @@ -180,7 +182,8 @@ ELG_Core::ELG_Core(const DL_Group& group, const BigInt& y, const BigInt& x) const BigInt& p = group.get_p(); p_bytes = p.bytes(); - BigInt k = random_integer(std::min(p.bits()-1, BLINDING_BITS)); + BigInt k = random_integer(global_state().prng_reference(), + std::min(p.bits()-1, BLINDING_BITS)); if(k != 0) blinder = Blinder(k, power_mod(k, x, p), p); } @@ -242,7 +245,8 @@ DH_Core::DH_Core(const DL_Group& group, const BigInt& x) op = Engine_Core::dh_op(group, x); const BigInt& p = group.get_p(); - BigInt k = random_integer(std::min(p.bits()-1, BLINDING_BITS)); + BigInt k = random_integer(global_state().prng_reference(), + std::min(p.bits()-1, BLINDING_BITS)); if(k != 0) blinder = Blinder(k, power_mod(inverse_mod(k, p), x, p), p); } diff --git a/src/rsa.cpp b/src/rsa.cpp index 6ddcd2415..e438c8b92 100644 --- a/src/rsa.cpp +++ b/src/rsa.cpp @@ -51,7 +51,9 @@ SecureVector<byte> RSA_PublicKey::verify(const byte in[], u32bit len) const /************************************************* * Create a RSA private key * *************************************************/ -RSA_PrivateKey::RSA_PrivateKey(u32bit bits, u32bit exp) +RSA_PrivateKey::RSA_PrivateKey(u32bit bits, + RandomNumberGenerator& rng, + u32bit exp) { if(bits < 1024) throw Invalid_Argument(algo_name() + ": Can't make a key that is only " + @@ -60,8 +62,8 @@ RSA_PrivateKey::RSA_PrivateKey(u32bit bits, u32bit exp) throw Invalid_Argument(algo_name() + ": Invalid encryption exponent"); e = exp; - p = random_prime((bits + 1) / 2, e); - q = random_prime(bits - p.bits(), e); + p = random_prime(rng, (bits + 1) / 2, e); + q = random_prime(rng, bits - p.bits(), e); d = inverse_mod(e, lcm(p - 1, q - 1)); PKCS8_load_hook(true); diff --git a/src/rw.cpp b/src/rw.cpp index 758a95a04..425ab83b3 100644 --- a/src/rw.cpp +++ b/src/rw.cpp @@ -52,17 +52,19 @@ SecureVector<byte> RW_PublicKey::verify(const byte in[], u32bit len) const /************************************************* * Create a Rabin-Williams private key * *************************************************/ -RW_PrivateKey::RW_PrivateKey(u32bit bits, u32bit exp) +RW_PrivateKey::RW_PrivateKey(u32bit bits, + RandomNumberGenerator& rng, + u32bit exp) { - if(bits < 512) + if(bits < 1024) throw Invalid_Argument(algo_name() + ": Can't make a key that is only " + to_string(bits) + " bits long"); if(exp < 2 || exp % 2 == 1) throw Invalid_Argument(algo_name() + ": Invalid encryption exponent"); e = exp; - p = random_prime((bits + 1) / 2, e / 2, 3, 4); - q = random_prime(bits - p.bits(), e / 2, ((p % 8 == 3) ? 7 : 3), 8); + p = random_prime(rng, (bits + 1) / 2, e / 2, 3, 4); + q = random_prime(rng, bits - p.bits(), e / 2, ((p % 8 == 3) ? 7 : 3), 8); d = inverse_mod(e, lcm(p - 1, q - 1) >> 1); PKCS8_load_hook(true); diff --git a/src/x509_ca.cpp b/src/x509_ca.cpp index 13e1520a1..602649930 100644 --- a/src/x509_ca.cpp +++ b/src/x509_ca.cpp @@ -91,13 +91,17 @@ X509_Certificate X509_CA::make_cert(PK_Signer* signer, const u32bit X509_CERT_VERSION = 3; const u32bit SERIAL_BITS = 128; + BigInt serial_no = random_integer(global_state().prng_reference(), + SERIAL_BITS); + DataSource_Memory source(X509_Object::make_signed(signer, sig_algo, DER_Encoder().start_cons(SEQUENCE) .start_explicit(0) .encode(X509_CERT_VERSION-1) .end_explicit() - .encode(random_integer(SERIAL_BITS)) + .encode(serial_no) + .encode(sig_algo) .encode(issuer_dn) |