Beispiel #1
0
        public async Task ForceReseed()
        {
            var sources = new IEntropySource[] { new CryptoRandomSource(64), new CurrentTimeSource(), new GCMemorySource(), new TimerSource(), new UserSuppliedSource(CypherBasedPrngGenerator.CreateWithCheapKey().GetRandomBytes(2048)) };
            var acc     = new EntropyAccumulator(new StandardRandomWrapperGenerator());
            var rng     = PooledEntropyCprngGenerator.Create(sources, accumulator: acc, config: Conf());

            Assert.AreEqual(rng.BytesRequested, 0);
            Assert.AreEqual(rng.ReseedCount, 0);
            Assert.AreEqual(rng.IsRunning, false);
            Assert.AreEqual(rng.EntropyPriority, EntropyPriority.High);
            Assert.AreEqual(rng.SourceCount, 5);

            await rng.StartAndWaitForFirstSeed();

            Assert.IsTrue(rng.ReseedCount >= 1);
            Assert.IsTrue(acc.TotalEntropyBytes > 0);
            Assert.AreNotEqual(rng.EntropyPriority, EntropyPriority.High);

            var reseedCount = rng.ReseedCount;
            var entropy     = acc.TotalEntropyBytes;
            await rng.Reseed();

            Assert.IsTrue(rng.ReseedCount > reseedCount);
            Assert.IsTrue(acc.TotalEntropyBytes > entropy);

            await rng.Stop();
        }
Beispiel #2
0
        public async Task CreatePrngFromPooled()
        {
            var sources = new IEntropySource[] { new CryptoRandomSource(64), new CurrentTimeSource(), new GCMemorySource(), new TimerSource(), new UserSuppliedSource(CypherBasedPrngGenerator.CreateWithCheapKey().GetRandomBytes(2048)) };
            var acc     = new EntropyAccumulator(new StandardRandomWrapperGenerator());
            var rng     = PooledEntropyCprngGenerator.Create(sources, accumulator: acc, config: Conf());

            Assert.AreEqual(rng.BytesRequested, 0);
            Assert.AreEqual(rng.ReseedCount, 0);
            Assert.AreEqual(rng.IsRunning, false);
            Assert.AreEqual(rng.EntropyPriority, EntropyPriority.High);
            Assert.AreEqual(rng.SourceCount, 5);

            await rng.StartAndWaitForFirstSeed();

            Assert.IsTrue(rng.ReseedCount >= 1);
            Assert.IsTrue(acc.TotalEntropyBytes > 0);
            System.Threading.Thread.Sleep(1);           // EntropyPriority is only updated after the reseed event, so it might not be current.
            Assert.AreNotEqual(rng.EntropyPriority, EntropyPriority.High);

            var prng = rng.CreateCypherBasedGenerator();

            Assert.IsNotNull(prng);

            var bytes = prng.GetRandomBytes(16);

            Assert.IsFalse(bytes.All(b => b == 0));

            await rng.Stop();
        }
Beispiel #3
0
 /// <summary>
 /// Creates a pooled random number generator that conforms to the Fortuna spec.
 /// This is more conservative than Terninger; no randomised pools or low priority mode.
 /// </summary>
 public static PooledEntropyCprngGenerator CreateFortuna() =>
 PooledEntropyCprngGenerator.Create(
     initialisedSources: BasicSources(),
     accumulator: new EntropyAccumulator(32, 0),
     config: new PooledEntropyCprngGenerator.PooledGeneratorConfig()
 {
     // Set the ways to enter low priority mode so high they should never be hit.
     ReseedCountBeforeSwitchToLowPriority = Int32.MaxValue,
     TimeBeforeSwitchToLowPriority        = TimeSpan.MaxValue,
     // Reseed more aggressively as well.
     MaximumBytesGeneratedBeforeReseed = 1024L * 1024L,
     MinimumTimeBetweenReseeds         = TimeSpan.FromHours(1),
 }
     );
Beispiel #4
0
        public async Task EventIsRaisedOnReseed()
        {
            var    sources          = new IEntropySource[] { new CryptoRandomSource(64), new CurrentTimeSource(), new GCMemorySource(), new TimerSource(), new UserSuppliedSource(CypherBasedPrngGenerator.CreateWithCheapKey().GetRandomBytes(2048)) };
            var    acc              = new EntropyAccumulator(new StandardRandomWrapperGenerator());
            var    rng              = PooledEntropyCprngGenerator.Create(sources, accumulator: acc, config: Conf());
            Object setInReseedEvent = null;

            rng.OnReseed += (o, e) => setInReseedEvent = new object();
            Assert.AreEqual(rng.BytesRequested, 0);
            Assert.AreEqual(rng.ReseedCount, 0);
            Assert.AreEqual(rng.IsRunning, false);
            Assert.AreEqual(rng.EntropyPriority, EntropyPriority.High);
            Assert.AreEqual(rng.SourceCount, 5);

            await rng.StartAndWaitForFirstSeed();

            Assert.IsNotNull(setInReseedEvent);

            await rng.Stop();
        }
Beispiel #5
0
        public async Task GetFirstSeed_MixedSyncAndAsyncSources()
        {
            var sources = new IEntropySource[] { new CryptoRandomSource(32), new CurrentTimeSource(), new GCMemorySource(), new TimerSource(), new AsyncCryptoRandomSource(), new ProcessStatsSource(), new NetworkStatsSource() };
            var acc     = new EntropyAccumulator(new StandardRandomWrapperGenerator());
            var rng     = PooledEntropyCprngGenerator.Create(sources, accumulator: acc, config: Conf());

            Assert.AreEqual(rng.BytesRequested, 0);
            Assert.AreEqual(rng.ReseedCount, 0);
            Assert.AreEqual(rng.IsRunning, false);
            Assert.AreEqual(rng.EntropyPriority, EntropyPriority.High);
            Assert.AreEqual(rng.SourceCount, 7);

            await rng.StartAndWaitForFirstSeed();

            Assert.IsTrue(rng.ReseedCount >= 1);
            Assert.IsTrue(acc.TotalEntropyBytes > 0);
            System.Threading.Thread.Sleep(1);           // EntropyPriority is only updated after the reseed event, so it might not be current.
            Assert.AreNotEqual(rng.EntropyPriority, EntropyPriority.High);

            await rng.Stop();
        }
Beispiel #6
0
        public async Task FirstSeedYieldsDifferentBytes()
        {
            var sources = new IEntropySource[] { new CryptoRandomSource(64), new CurrentTimeSource(), new GCMemorySource(), new TimerSource(), new UserSuppliedSource(CypherBasedPrngGenerator.CreateWithCheapKey().GetRandomBytes(2048)) };
            var acc1    = new EntropyAccumulator(new StandardRandomWrapperGenerator());
            var rng1    = PooledEntropyCprngGenerator.Create(sources, accumulator: acc1, config: Conf());
            await rng1.StartAndWaitForFirstSeed();

            var acc2 = new EntropyAccumulator(new StandardRandomWrapperGenerator());
            var rng2 = PooledEntropyCprngGenerator.Create(sources, accumulator: acc2, config: Conf());
            await rng2.StartAndWaitForFirstSeed();

            var bytesFrom1 = rng1.GetRandomBytes(64);

            Assert.IsFalse(bytesFrom1.All(b => b == 0));
            var bytesFrom2 = rng2.GetRandomBytes(64);

            Assert.IsFalse(bytesFrom2.All(b => b == 0));
            // Expect two generates with different inputs will give different bytes from from the start.
            Assert.IsFalse(bytesFrom1.SequenceEqual(bytesFrom2));

            await rng1.Stop();

            await rng2.Stop();
        }
Beispiel #7
0
 /// <summary>
 /// Creates a pooled random number generator that makes improvements and changes to the Fortuna spec.
 /// This allows for less CPU usage, uses randomised pools, but isn't "official".
 /// </summary>
 public static PooledEntropyCprngGenerator CreateTerninger() =>
 PooledEntropyCprngGenerator.Create(
     initialisedSources: BasicSources(),
     accumulator: new EntropyAccumulator(16, 16, CypherBasedPrngGenerator.CreateWithCheapKey())
     );