diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index bc3a95b8ca..d085e5b3e7 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -797,6 +797,17 @@ void Random::setSeed (const int64 newSeed) throw() seed = newSeed; } +void Random::setSeedRandomly() +{ + Random r1 (SystemStats::getClockCycleCounter()); + Random r2 (Time::getHighResolutionTicks()); + Random r3 (Time::getHighResolutionTicksPerSecond()); + Random r4 (Time::currentTimeMillis()); + + setSeed (r1.nextInt64() ^ r2.nextInt64() + ^ r3.nextInt64() ^ r4.nextInt64()); +} + int Random::nextInt() throw() { seed = (seed * literal64bit (0x5deece66d) + 11) & literal64bit (0xffffffffffff); @@ -1114,7 +1125,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() DBG (SystemStats::getJUCEVersion()); juce_initialiseStrings(); SystemStats::initialiseStats(); - Random::getSystemRandom().setSeed (Time::currentTimeMillis()); + Random::getSystemRandom().setSeedRandomly(); } } @@ -4061,14 +4072,44 @@ static bool findCandidate (const BitArray& base, } const BitArray Primes::createProbablePrime (const int bitLength, - const int certainty) throw() + const int certainty, + const int* randomSeeds, + int numRandomSeeds) throw() { + int defaultSeeds[8]; + + if (numRandomSeeds <= 0) + { + randomSeeds = defaultSeeds; + numRandomSeeds = 8; + + for (int j = 10; --j >= 0;) + { + Random r (0); + r.setSeedRandomly(); + + for (int i = numRandomSeeds; --i >= 0;) + defaultSeeds[i] ^= r.nextInt() ^ Random::getSystemRandom().nextInt(); + } + } + BitArray smallSieve; const int smallSieveSize = 15000; createSmallSieve (smallSieveSize, smallSieve); BitArray p; - p.fillBitsRandomly (0, bitLength); + + for (int i = numRandomSeeds; --i >= 0;) + { + Random::getSystemRandom().setSeed (randomSeeds[i]); + + BitArray p2; + p2.fillBitsRandomly (0, bitLength); + p.xorWith (p2); + } + + Random::getSystemRandom().setSeedRandomly(); + p.setBit (bitLength - 1); p.clearBit (0); @@ -4267,12 +4308,14 @@ static const BitArray findBestCommonDivisor (const BitArray& p, void RSAKey::createKeyPair (RSAKey& publicKey, RSAKey& privateKey, - const int numBits) throw() + const int numBits, + const int* randomSeeds, + const int numRandomSeeds) throw() { jassert (numBits > 16); // not much point using less than this.. - BitArray p (Primes::createProbablePrime (numBits / 2, 30)); - BitArray q (Primes::createProbablePrime (numBits - numBits / 2, 30)); + BitArray p (Primes::createProbablePrime (numBits / 2, 30, randomSeeds, numRandomSeeds)); + BitArray q (Primes::createProbablePrime (numBits - numBits / 2, 30, randomSeeds, numRandomSeeds)); BitArray n (p); n.multiplyBy (q); // n = pq @@ -189241,6 +189284,9 @@ public: { if (ok) { + // write a zero-length packet to show ogg that we're finished.. + write (0, 0); + ogg_stream_clear (&os); vorbis_block_clear (&vb); vorbis_dsp_clear (&vd); diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 7d01680eb4..c57643cf05 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -7056,6 +7056,11 @@ public: /** Resets this Random object to a given seed value. */ void setSeed (const int64 newSeed) throw(); + /** Reseeds this generator using a value generated from various semi-random system + properties like the current time, etc. + */ + void setSeedRandomly(); + juce_UseDebuggingNewOperator private: @@ -11860,9 +11865,15 @@ public: The certainty parameter specifies how many iterations to use when testing for primality. A safe value might be anything over about 20-30. + + The randomSeeds parameter lets you optionally pass it a set of values with + which to seed the random number generation, improving the security of the + keys generated. */ static const BitArray createProbablePrime (int bitLength, - int certainty) throw(); + int certainty, + const int* randomSeeds = 0, + int numRandomSeeds = 0) throw(); /** Tests a number to see if it's prime. @@ -11933,10 +11944,16 @@ public: The numBits parameter specifies the size of key, e.g. 128, 256, 512 bit. Bigger sizes are more secure, but this method will take longer to execute. + + The randomSeeds parameter lets you optionally pass it a set of values with + which to seed the random number generation, improving the security of the + keys generated. */ static void createKeyPair (RSAKey& publicKey, RSAKey& privateKey, - const int numBits) throw(); + const int numBits, + const int* randomSeeds = 0, + const int numRandomSeeds = 0) throw(); juce_UseDebuggingNewOperator diff --git a/src/juce_core/basics/juce_Random.cpp b/src/juce_core/basics/juce_Random.cpp index 346e602b15..64b02ad95f 100644 --- a/src/juce_core/basics/juce_Random.cpp +++ b/src/juce_core/basics/juce_Random.cpp @@ -34,6 +34,9 @@ BEGIN_JUCE_NAMESPACE #include "juce_Random.h" +#include "../basics/juce_Time.h" +#include "../basics/juce_SystemStats.h" + //============================================================================== Random::Random (const int64 seedValue) throw() @@ -50,6 +53,17 @@ void Random::setSeed (const int64 newSeed) throw() seed = newSeed; } +void Random::setSeedRandomly() +{ + Random r1 (SystemStats::getClockCycleCounter()); + Random r2 (Time::getHighResolutionTicks()); + Random r3 (Time::getHighResolutionTicksPerSecond()); + Random r4 (Time::currentTimeMillis()); + + setSeed (r1.nextInt64() ^ r2.nextInt64() + ^ r3.nextInt64() ^ r4.nextInt64()); +} + //============================================================================== int Random::nextInt() throw() { diff --git a/src/juce_core/basics/juce_Random.h b/src/juce_core/basics/juce_Random.h index 7df02836f3..b85c294a8f 100644 --- a/src/juce_core/basics/juce_Random.h +++ b/src/juce_core/basics/juce_Random.h @@ -100,6 +100,11 @@ public: /** Resets this Random object to a given seed value. */ void setSeed (const int64 newSeed) throw(); + /** Reseeds this generator using a value generated from various semi-random system + properties like the current time, etc. + */ + void setSeedRandomly(); + //============================================================================== juce_UseDebuggingNewOperator diff --git a/src/juce_core/basics/juce_SystemStats.cpp b/src/juce_core/basics/juce_SystemStats.cpp index 1edc7c1683..6209c6e326 100644 --- a/src/juce_core/basics/juce_SystemStats.cpp +++ b/src/juce_core/basics/juce_SystemStats.cpp @@ -86,7 +86,7 @@ void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI() DBG (SystemStats::getJUCEVersion()); juce_initialiseStrings(); SystemStats::initialiseStats(); - Random::getSystemRandom().setSeed (Time::currentTimeMillis()); + Random::getSystemRandom().setSeedRandomly(); } } diff --git a/src/juce_core/cryptography/juce_Primes.cpp b/src/juce_core/cryptography/juce_Primes.cpp index f9a18dfde1..23a078cf1c 100644 --- a/src/juce_core/cryptography/juce_Primes.cpp +++ b/src/juce_core/cryptography/juce_Primes.cpp @@ -35,6 +35,7 @@ BEGIN_JUCE_NAMESPACE #include "juce_Primes.h" +#include "../basics/juce_Random.h" //============================================================================== @@ -121,14 +122,44 @@ static bool findCandidate (const BitArray& base, //============================================================================== const BitArray Primes::createProbablePrime (const int bitLength, - const int certainty) throw() + const int certainty, + const int* randomSeeds, + int numRandomSeeds) throw() { + int defaultSeeds[8]; + + if (numRandomSeeds <= 0) + { + randomSeeds = defaultSeeds; + numRandomSeeds = 8; + + for (int j = 10; --j >= 0;) + { + Random r (0); + r.setSeedRandomly(); + + for (int i = numRandomSeeds; --i >= 0;) + defaultSeeds[i] ^= r.nextInt() ^ Random::getSystemRandom().nextInt(); + } + } + BitArray smallSieve; const int smallSieveSize = 15000; createSmallSieve (smallSieveSize, smallSieve); BitArray p; - p.fillBitsRandomly (0, bitLength); + + for (int i = numRandomSeeds; --i >= 0;) + { + Random::getSystemRandom().setSeed (randomSeeds[i]); + + BitArray p2; + p2.fillBitsRandomly (0, bitLength); + p.xorWith (p2); + } + + Random::getSystemRandom().setSeedRandomly(); + p.setBit (bitLength - 1); p.clearBit (0); diff --git a/src/juce_core/cryptography/juce_Primes.h b/src/juce_core/cryptography/juce_Primes.h index 68a1415693..7ac83fbd25 100644 --- a/src/juce_core/cryptography/juce_Primes.h +++ b/src/juce_core/cryptography/juce_Primes.h @@ -51,9 +51,15 @@ public: The certainty parameter specifies how many iterations to use when testing for primality. A safe value might be anything over about 20-30. + + The randomSeeds parameter lets you optionally pass it a set of values with + which to seed the random number generation, improving the security of the + keys generated. */ static const BitArray createProbablePrime (int bitLength, - int certainty) throw(); + int certainty, + const int* randomSeeds = 0, + int numRandomSeeds = 0) throw(); /** Tests a number to see if it's prime. diff --git a/src/juce_core/cryptography/juce_RSAKey.cpp b/src/juce_core/cryptography/juce_RSAKey.cpp index 07045dc8df..ee4e68fb0b 100644 --- a/src/juce_core/cryptography/juce_RSAKey.cpp +++ b/src/juce_core/cryptography/juce_RSAKey.cpp @@ -126,12 +126,14 @@ static const BitArray findBestCommonDivisor (const BitArray& p, void RSAKey::createKeyPair (RSAKey& publicKey, RSAKey& privateKey, - const int numBits) throw() + const int numBits, + const int* randomSeeds, + const int numRandomSeeds) throw() { jassert (numBits > 16); // not much point using less than this.. - BitArray p (Primes::createProbablePrime (numBits / 2, 30)); - BitArray q (Primes::createProbablePrime (numBits - numBits / 2, 30)); + BitArray p (Primes::createProbablePrime (numBits / 2, 30, randomSeeds, numRandomSeeds)); + BitArray q (Primes::createProbablePrime (numBits - numBits / 2, 30, randomSeeds, numRandomSeeds)); BitArray n (p); n.multiplyBy (q); // n = pq diff --git a/src/juce_core/cryptography/juce_RSAKey.h b/src/juce_core/cryptography/juce_RSAKey.h index 156aa35cb4..a02d1bcf0f 100644 --- a/src/juce_core/cryptography/juce_RSAKey.h +++ b/src/juce_core/cryptography/juce_RSAKey.h @@ -86,10 +86,16 @@ public: The numBits parameter specifies the size of key, e.g. 128, 256, 512 bit. Bigger sizes are more secure, but this method will take longer to execute. + + The randomSeeds parameter lets you optionally pass it a set of values with + which to seed the random number generation, improving the security of the + keys generated. */ static void createKeyPair (RSAKey& publicKey, RSAKey& privateKey, - const int numBits) throw(); + const int numBits, + const int* randomSeeds = 0, + const int numRandomSeeds = 0) throw(); //==============================================================================