diff --git a/crypto/src/security/SecureRandom.cs b/crypto/src/security/SecureRandom.cs
index c91b5ee91..160628d4b 100644
--- a/crypto/src/security/SecureRandom.cs
+++ b/crypto/src/security/SecureRandom.cs
@@ -8,223 +8,223 @@ using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Security
{
public class SecureRandom
- : Random
+ : Random
{
- // Note: all objects of this class should be deriving their random data from
- // a single generator appropriate to the digest being used.
- private static readonly IRandomGenerator sha1Generator = new DigestRandomGenerator(new Sha1Digest());
- private static readonly IRandomGenerator sha256Generator = new DigestRandomGenerator(new Sha256Digest());
-
- private static readonly SecureRandom[] master = { null };
- private static SecureRandom Master
- {
- get
- {
- if (master[0] == null)
- {
- SecureRandom sr = master[0] = new SecureRandom(sha256Generator);
-
- // Even though Ticks has at most 8 or 14 bits of entropy, there's no harm in adding it.
- sr.SetSeed(DateTime.Now.Ticks);
- // In addition to Ticks and ThreadedSeedGenerator, also seed from CryptoApiRandomGenerator
- CryptoApiRandomGenerator systemRNG = new CryptoApiRandomGenerator();
- byte[] systemSeed = new byte[32];
- systemRNG.NextBytes(systemSeed);
- sr.SetSeed(systemSeed);
- Array.Clear(systemSeed,0,systemSeed.Length);
- // 32 will be enough when ThreadedSeedGenerator is fixed. Until then, ThreadedSeedGenerator returns low
- // entropy, and this is not sufficient to be secure. http://www.bouncycastle.org/csharpdevmailarchive/msg00814.html
- sr.SetSeed(new ThreadedSeedGenerator().GenerateSeed(32, true));
- }
-
- return master[0];
- }
- }
-
- public static SecureRandom GetInstance(
- string algorithm)
- {
- // TODO Support all digests more generally, by stripping PRNG and calling DigestUtilities?
- string drgName = Platform.ToUpperInvariant(algorithm);
-
- if (drgName == "SHA1PRNG")
- {
- SecureRandom newPrng = new SecureRandom(sha1Generator);
- newPrng.SetSeed(GetSeed(20));
- return newPrng;
- }
- else if (drgName == "SHA256PRNG")
- {
- SecureRandom newPrng = new SecureRandom(sha256Generator);
- newPrng.SetSeed(GetSeed(32));
- return newPrng;
- }
-
- throw new ArgumentException("Unrecognised PRNG algorithm: " + algorithm, "algorithm");
- }
-
- public static byte[] GetSeed(
- int length)
- {
- return Master.GenerateSeed(length);
- }
-
- protected IRandomGenerator generator;
-
- public SecureRandom()
- : this(sha1Generator)
- {
- SetSeed(GetSeed(20)); // 20 bytes because this is sha1Generator
- }
-
- public SecureRandom(
- byte[] inSeed)
- : this(sha1Generator)
- {
- SetSeed(inSeed);
- }
-
- /// <summary>Use the specified instance of IRandomGenerator as random source.</summary>
- /// <remarks>
- /// This constructor performs no seeding of either the <c>IRandomGenerator</c> or the
- /// constructed <c>SecureRandom</c>. It is the responsibility of the client to provide
- /// proper seed material as necessary/appropriate for the given <c>IRandomGenerator</c>
- /// implementation.
- /// </remarks>
- /// <param name="generator">The source to generate all random bytes from.</param>
- public SecureRandom(
- IRandomGenerator generator)
- : base(0)
- {
- this.generator = generator;
- }
-
- public virtual byte[] GenerateSeed(
- int length)
- {
- SetSeed(DateTime.Now.Ticks);
-
- byte[] rv = new byte[length];
- NextBytes(rv);
- return rv;
- }
-
- public virtual void SetSeed(
- byte[] inSeed)
- {
- generator.AddSeedMaterial(inSeed);
+ // Note: all objects of this class should be deriving their random data from
+ // a single generator appropriate to the digest being used.
+ private static readonly IRandomGenerator sha1Generator = new DigestRandomGenerator(new Sha1Digest());
+ private static readonly IRandomGenerator sha256Generator = new DigestRandomGenerator(new Sha256Digest());
+
+ private static readonly SecureRandom[] master = { null };
+ private static SecureRandom Master
+ {
+ get
+ {
+ if (master[0] == null)
+ {
+ SecureRandom sr = master[0] = new SecureRandom(sha256Generator);
+
+ // Even though Ticks has at most 8 or 14 bits of entropy, there's no harm in adding it.
+ sr.SetSeed(DateTime.Now.Ticks);
+ // In addition to Ticks and ThreadedSeedGenerator, also seed from CryptoApiRandomGenerator
+ CryptoApiRandomGenerator systemRNG = new CryptoApiRandomGenerator();
+ byte[] systemSeed = new byte[32];
+ systemRNG.NextBytes(systemSeed);
+ sr.SetSeed(systemSeed);
+ Array.Clear(systemSeed,0,systemSeed.Length);
+ // 32 will be enough when ThreadedSeedGenerator is fixed. Until then, ThreadedSeedGenerator returns low
+ // entropy, and this is not sufficient to be secure. http://www.bouncycastle.org/csharpdevmailarchive/msg00814.html
+ sr.SetSeed(new ThreadedSeedGenerator().GenerateSeed(32, true));
+ }
+
+ return master[0];
+ }
+ }
+
+ public static SecureRandom GetInstance(
+ string algorithm)
+ {
+ // TODO Support all digests more generally, by stripping PRNG and calling DigestUtilities?
+ string drgName = Platform.ToUpperInvariant(algorithm);
+
+ if (drgName == "SHA1PRNG")
+ {
+ SecureRandom newPrng = new SecureRandom(sha1Generator);
+ newPrng.SetSeed(GetSeed(20));
+ return newPrng;
+ }
+ else if (drgName == "SHA256PRNG")
+ {
+ SecureRandom newPrng = new SecureRandom(sha256Generator);
+ newPrng.SetSeed(GetSeed(32));
+ return newPrng;
+ }
+
+ throw new ArgumentException("Unrecognised PRNG algorithm: " + algorithm, "algorithm");
+ }
+
+ public static byte[] GetSeed(
+ int length)
+ {
+ return Master.GenerateSeed(length);
+ }
+
+ protected IRandomGenerator generator;
+
+ public SecureRandom()
+ : this(sha1Generator)
+ {
+ SetSeed(GetSeed(20)); // 20 bytes because this is sha1Generator
+ }
+
+ public SecureRandom(
+ byte[] inSeed)
+ : this(sha1Generator)
+ {
+ SetSeed(inSeed);
+ }
+
+ /// <summary>Use the specified instance of IRandomGenerator as random source.</summary>
+ /// <remarks>
+ /// This constructor performs no seeding of either the <c>IRandomGenerator</c> or the
+ /// constructed <c>SecureRandom</c>. It is the responsibility of the client to provide
+ /// proper seed material as necessary/appropriate for the given <c>IRandomGenerator</c>
+ /// implementation.
+ /// </remarks>
+ /// <param name="generator">The source to generate all random bytes from.</param>
+ public SecureRandom(
+ IRandomGenerator generator)
+ : base(0)
+ {
+ this.generator = generator;
+ }
+
+ public virtual byte[] GenerateSeed(
+ int length)
+ {
+ SetSeed(DateTime.Now.Ticks);
+
+ byte[] rv = new byte[length];
+ NextBytes(rv);
+ return rv;
}
public virtual void SetSeed(
- long seed)
- {
- generator.AddSeedMaterial(seed);
- }
-
- public override int Next()
- {
- for (;;)
- {
- int i = NextInt() & int.MaxValue;
-
- if (i != int.MaxValue)
- return i;
- }
- }
-
- public override int Next(
- int maxValue)
- {
- if (maxValue < 2)
- {
- if (maxValue < 0)
- throw new ArgumentOutOfRangeException("maxValue", "cannot be negative");
-
- return 0;
- }
-
- // Test whether maxValue is a power of 2
- if ((maxValue & -maxValue) == maxValue)
- {
- int val = NextInt() & int.MaxValue;
- long lr = ((long) maxValue * (long) val) >> 31;
- return (int) lr;
- }
-
- int bits, result;
- do
- {
- bits = NextInt() & int.MaxValue;
- result = bits % maxValue;
- }
- while (bits - result + (maxValue - 1) < 0); // Ignore results near overflow
-
- return result;
- }
-
- public override int Next(
- int minValue,
- int maxValue)
- {
- if (maxValue <= minValue)
- {
- if (maxValue == minValue)
- return minValue;
-
- throw new ArgumentException("maxValue cannot be less than minValue");
- }
-
- int diff = maxValue - minValue;
- if (diff > 0)
- return minValue + Next(diff);
-
- for (;;)
- {
- int i = NextInt();
-
- if (i >= minValue && i < maxValue)
- return i;
- }
- }
-
- public override void NextBytes(
- byte[] buffer)
- {
- generator.NextBytes(buffer);
- }
-
- public virtual void NextBytes(
- byte[] buffer,
- int start,
- int length)
- {
- generator.NextBytes(buffer, start, length);
- }
-
- private static readonly double DoubleScale = System.Math.Pow(2.0, 64.0);
-
- public override double NextDouble()
- {
- return Convert.ToDouble((ulong) NextLong()) / DoubleScale;
- }
-
- public virtual int NextInt()
- {
- byte[] intBytes = new byte[4];
+ byte[] inSeed)
+ {
+ generator.AddSeedMaterial(inSeed);
+ }
+
+ public virtual void SetSeed(
+ long seed)
+ {
+ generator.AddSeedMaterial(seed);
+ }
+
+ public override int Next()
+ {
+ for (;;)
+ {
+ int i = NextInt() & int.MaxValue;
+
+ if (i != int.MaxValue)
+ return i;
+ }
+ }
+
+ public override int Next(
+ int maxValue)
+ {
+ if (maxValue < 2)
+ {
+ if (maxValue < 0)
+ throw new ArgumentOutOfRangeException("maxValue", "cannot be negative");
+
+ return 0;
+ }
+
+ // Test whether maxValue is a power of 2
+ if ((maxValue & -maxValue) == maxValue)
+ {
+ int val = NextInt() & int.MaxValue;
+ long lr = ((long) maxValue * (long) val) >> 31;
+ return (int) lr;
+ }
+
+ int bits, result;
+ do
+ {
+ bits = NextInt() & int.MaxValue;
+ result = bits % maxValue;
+ }
+ while (bits - result + (maxValue - 1) < 0); // Ignore results near overflow
+
+ return result;
+ }
+
+ public override int Next(
+ int minValue,
+ int maxValue)
+ {
+ if (maxValue <= minValue)
+ {
+ if (maxValue == minValue)
+ return minValue;
+
+ throw new ArgumentException("maxValue cannot be less than minValue");
+ }
+
+ int diff = maxValue - minValue;
+ if (diff > 0)
+ return minValue + Next(diff);
+
+ for (;;)
+ {
+ int i = NextInt();
+
+ if (i >= minValue && i < maxValue)
+ return i;
+ }
+ }
+
+ public override void NextBytes(
+ byte[] buffer)
+ {
+ generator.NextBytes(buffer);
+ }
+
+ public virtual void NextBytes(
+ byte[] buffer,
+ int start,
+ int length)
+ {
+ generator.NextBytes(buffer, start, length);
+ }
+
+ private static readonly double DoubleScale = System.Math.Pow(2.0, 64.0);
+
+ public override double NextDouble()
+ {
+ return Convert.ToDouble((ulong) NextLong()) / DoubleScale;
+ }
+
+ public virtual int NextInt()
+ {
+ byte[] intBytes = new byte[4];
NextBytes(intBytes);
- int result = 0;
+ int result = 0;
for (int i = 0; i < 4; i++)
{
result = (result << 8) + (intBytes[i] & 0xff);
}
- return result;
+ return result;
}
- public virtual long NextLong()
- {
- return ((long)(uint) NextInt() << 32) | (long)(uint) NextInt();
- }
+ public virtual long NextLong()
+ {
+ return ((long)(uint) NextInt() << 32) | (long)(uint) NextInt();
+ }
}
}
|