Exemple #1
0
        public async Task CypherGenerator_LocalAndCheapKeyWithExtraEntropy()
        {
            var key = SHA256.Create().ComputeHash((await StaticLocalEntropy.Get32()).Concat(CheapEntropy.Get32()).ToArray());
            var rng = CypherBasedPrngGenerator.Create(key, additionalEntropyGetter: CheapEntropy.Get16);

            await FuzzGenerator(10000, 1, 64, rng, nameof(CypherBasedPrngGenerator) + "_LocalAndCheapKeyAndExtraEntropy");
        }
Exemple #2
0
        public void ConstructAesCspCrng()
        {
            var crng = new CypherBasedPrngGenerator(_ZeroKey32Bytes, NativeCryptoPrimitives.GetAes256Csp(), SHA256.Create(), new CypherCounter(16));

            // Creating a generator should not actually generate any bytes.
            Assert.AreEqual(crng.BytesGenerated, 0L);
            Assert.AreEqual(crng.BytesRequested, 0L);
        }
Exemple #3
0
        public void ConstructDefaultCrng()
        {
            var crng = new CypherBasedPrngGenerator(_ZeroKey32Bytes);

            // Creating a generator should not actually generate any bytes.
            Assert.AreEqual(crng.BytesGenerated, 0L);
            Assert.AreEqual(crng.BytesRequested, 0L);
        }
Exemple #4
0
        public void GenerateTwiceMaximumSingleRequestBytes()
        {
            var crng   = new CypherBasedPrngGenerator(_ZeroKey32Bytes);
            var result = crng.GetRandomBytes(crng.MaxRequestBytes * 2);

            Assert.AreEqual(crng.BytesGenerated, result.Length + 64);
            Assert.AreEqual(crng.BytesRequested, result.Length);
        }
Exemple #5
0
        public void GenerateFourBytes()
        {
            var crng   = CypherBasedPrngGenerator.Create(_ZeroKey32Bytes, outputBufferSize: 0);
            var result = crng.GetRandomBytes(4);

            Assert.AreEqual(crng.BytesGenerated, crng.BlockSizeBytes + 32);
            Assert.AreEqual(crng.BytesRequested, result.Length);
        }
        public void Get10RandomGuids()
        {
            var prng = new CypherBasedPrngGenerator(new byte[32]);

            for (int i = 0; i < 10; i++)
            {
                prng.GetRandomGuid();
            }
        }
Exemple #7
0
        public void Sha384AgorithmWorks()
        {
            var crngSha384 = new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256Managed(), SHA384.Create(), new CypherCounter(16));
            var buffer384  = new byte[crngSha384.BlockSizeBytes * 2];

            crngSha384.FillWithRandomBytes(buffer384);

            Assert.IsFalse(buffer384.All(b => b == 0));
        }
Exemple #8
0
        public void Sha1AndAes128Works()
        {
            var crng   = new CypherBasedPrngGenerator(_ZeroKey16Bytes, CryptoPrimitive.Aes128Managed(), SHA1.Create(), new CypherCounter(16));
            var buffer = new byte[crng.BlockSizeBytes * 2];

            crng.FillWithRandomBytes(buffer);

            Assert.IsFalse(buffer.All(b => b == 0));
        }
Exemple #9
0
        public void Rijndael256Key256BlockWorks()
        {
            var crng   = new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.RijndaelManaged(256, 256), SHA256.Create(), new CypherCounter(32));
            var buffer = new byte[crng.BlockSizeBytes * 2];

            crng.FillWithRandomBytes(buffer);

            Assert.IsFalse(buffer.All(b => b == 0));
        }
Exemple #10
0
        public void Hmac256CryptoPrimitiveWorks()
        {
            var crng   = new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.HmacSha256(), SHA256.Create(), new CypherCounter(32));
            var buffer = new byte[crng.BlockSizeBytes * 2];

            crng.FillWithRandomBytes(buffer);

            Assert.IsFalse(buffer.All(b => b == 0));
        }
Exemple #11
0
        public void Sha512CryptoPrimitiveWorks()
        {
            var crng   = new CypherBasedPrngGenerator(_ZeroKey64Bytes, CryptoPrimitive.Sha512(), SHA512.Create(), new CypherCounter(64));
            var buffer = new byte[crng.BlockSizeBytes * 2];

            crng.FillWithRandomBytes(buffer);

            Assert.IsFalse(buffer.All(b => b == 0));
        }
Exemple #12
0
        public void GenerateTwoBlocksInOneRequest()
        {
            var crng   = CypherBasedPrngGenerator.Create(_ZeroKey32Bytes, outputBufferSize: 0);
            var buffer = new byte[crng.BlockSizeBytes * 2];

            crng.FillWithRandomBytes(buffer);

            Assert.IsFalse(buffer.All(b => b == 0));
            Assert.AreEqual(crng.BytesGenerated, buffer.Length + 32);
            Assert.AreEqual(crng.BytesRequested, buffer.Length);
        }
Exemple #13
0
        public void GenerateSingleBlockAesCsp()
        {
            var crng   = new CypherBasedPrngGenerator(_ZeroKey32Bytes, NativeCryptoPrimitives.GetAes256Csp(), SHA256.Create(), new CypherCounter(16), 0);
            var buffer = new byte[crng.BlockSizeBytes];

            crng.FillWithRandomBytes(buffer);

            Assert.IsFalse(buffer.All(b => b == 0));
            Assert.AreEqual(crng.BytesGenerated, buffer.Length + (crng.BlockSizeBytes * 2));
            Assert.AreEqual(crng.BytesRequested, buffer.Length);
        }
Exemple #14
0
        public void GeneratorsWithDifferentKeyYieldDifferentResult()
        {
            var crng1   = new CypherBasedPrngGenerator(_ZeroKey32Bytes);
            var crng2   = new CypherBasedPrngGenerator(_IncrementedKey32Bytes);
            var buffer1 = new byte[crng1.BlockSizeBytes];
            var buffer2 = new byte[crng2.BlockSizeBytes];

            crng1.FillWithRandomBytes(buffer1);
            crng2.FillWithRandomBytes(buffer2);

            Assert.IsFalse(buffer1.SequenceEqual(buffer2));
        }
Exemple #15
0
        /// <summary>
        /// Creates a light weight PRNG from a Pooled Generator.
        /// If the Pooled Generator has not created its first seed, this will throw.
        /// </summary>
        public static IRandomNumberGenerator CreateCypherBasedGenerator(this PooledEntropyCprngGenerator pooledRng, int bufferSize)
        {
            if (pooledRng == null)
            {
                throw new ArgumentNullException(nameof(pooledRng));
            }

            var key    = pooledRng.GetRandomBytes(32);
            var result = CypherBasedPrngGenerator.Create(key, outputBufferSize: bufferSize);

            return(result);
        }
Exemple #16
0
        public void GeneratorsWithSameKeyYieldSameResult()
        {
            var crng1   = new CypherBasedPrngGenerator(_ZeroKey32Bytes);
            var crng2   = new CypherBasedPrngGenerator(_ZeroKey32Bytes);
            var buffer1 = new byte[crng1.BlockSizeBytes];
            var buffer2 = new byte[crng2.BlockSizeBytes];

            crng1.FillWithRandomBytes(buffer1);
            crng2.FillWithRandomBytes(buffer2);

            Assert.IsTrue(buffer1.SequenceEqual(buffer2));
        }
Exemple #17
0
        public void ConstructWithPrng()
        {
            var sources = new IEntropySource[] { new NullSource(), new NullSource() };
            var prng    = new CypherBasedPrngGenerator(new StandardRandomWrapperGenerator().GetRandomBytes(32));
            var rng     = new PooledEntropyCprngGenerator(sources, prng);

            // Creating a generator should not actually generate any bytes or even start the generator.
            Assert.AreEqual(rng.BytesRequested, 0);
            Assert.AreEqual(rng.ReseedCount, 0);
            Assert.AreEqual(rng.IsRunning, false);
            Assert.AreEqual(rng.EntropyPriority, EntropyPriority.High);
        }
Exemple #18
0
        public void SameCypherWithDifferentCountersProduceDifferentRandomBlocks()
        {
            var crng1   = new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256(), SHA256.Create(), new CypherCounter(16, 1));
            var crng2   = new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256(), SHA256.Create(), new CypherCounter(16, 2));
            var buffer1 = new byte[crng1.BlockSizeBytes * 2];
            var buffer2 = new byte[crng2.BlockSizeBytes * 2];

            crng1.FillWithRandomBytes(buffer1);
            crng2.FillWithRandomBytes(buffer2);

            CollectionAssert.AreNotEqual(buffer1, buffer2);
        }
Exemple #19
0
        public void Aes128And256CyphersProduceDifferentRandomBlocks()
        {
            var crngAes128 = new CypherBasedPrngGenerator(_ZeroKey16Bytes, CryptoPrimitive.Aes128Managed(), SHA256.Create(), new CypherCounter(16));
            var crngAes256 = new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256Managed(), SHA256.Create(), new CypherCounter(16));
            var buffer128  = new byte[crngAes128.BlockSizeBytes * 4];
            var buffer256  = new byte[crngAes256.BlockSizeBytes * 2];

            crngAes128.FillWithRandomBytes(buffer128);
            crngAes256.FillWithRandomBytes(buffer256);

            CollectionAssert.AreNotEqual(buffer128, buffer256);
        }
Exemple #20
0
        public void Sha256And512AlgorithmsProduceDifferentRandomBlocks()
        {
            var crngSha256 = new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256Managed(), SHA256.Create(), new CypherCounter(16));
            var crngSha512 = new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256Managed(), SHA512.Create(), new CypherCounter(16));
            var buffer256  = new byte[crngSha256.BlockSizeBytes * 2];
            var buffer512  = new byte[crngSha512.BlockSizeBytes * 2];

            crngSha256.FillWithRandomBytes(buffer256);
            crngSha512.FillWithRandomBytes(buffer512);

            CollectionAssert.AreNotEqual(buffer256, buffer512);
        }
Exemple #21
0
        public void SameCypherAndKeyButAdditionalEntropyProduceDifferentRandomBlocks32Bytes()
        {
            var crng1   = new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256(), SHA256.Create(), new CypherCounter(16), 0, CheapEntropy.Get32);
            var crng2   = new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256(), SHA256.Create(), new CypherCounter(16), 0, CheapEntropy.Get32);
            var buffer1 = new byte[crng1.BlockSizeBytes * 2];
            var buffer2 = new byte[crng2.BlockSizeBytes * 2];

            crng1.FillWithRandomBytes(buffer1);
            crng2.FillWithRandomBytes(buffer2);

            CollectionAssert.AreNotEqual(buffer1, buffer2);
        }
Exemple #22
0
        public void AesCyphersProduceSameRandomBlocks()
        {
            var crngManaged   = new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256Managed(), SHA256.Create(), new CypherCounter(16));
            var crngCsp       = new CypherBasedPrngGenerator(_ZeroKey32Bytes, NativeCryptoPrimitives.GetAes256Csp(), SHA256.Create(), new CypherCounter(16));
            var bufferManaged = new byte[crngManaged.BlockSizeBytes * 2];
            var bufferCsp     = new byte[crngManaged.BlockSizeBytes * 2];

            crngManaged.FillWithRandomBytes(bufferManaged);
            crngCsp.FillWithRandomBytes(bufferCsp);

            CollectionAssert.AreEqual(bufferManaged, bufferCsp);
        }
Exemple #23
0
        public void BufferedGeneratorCopesWithAllSizedRequests()
        {
            var crng   = CypherBasedPrngGenerator.Create(_ZeroKey32Bytes, outputBufferSize: 1024);
            var buffer = new byte[1280];

            for (int i = 1; i < 1280; i++)
            {
                crng.FillWithRandomBytes(buffer, 0, i);
                Assert.IsFalse(buffer.All(b => b == 0));
                Array.Clear(buffer, 0, buffer.Length);
            }
        }
        public void RandomGuid_Fuzzing()
        {
            var prng = new CypherBasedPrngGenerator(new byte[32]);

            // Dumps 100000 random guids.
            using (var sw = new StreamWriter(nameof(RandomGuid_Fuzzing) + ".raw.txt", false, Encoding.UTF8))
            {
                for (int i = 0; i < 100000; i++)
                {
                    var theVal = prng.GetRandomGuid();
                    sw.WriteLine(theVal);
                }
            }
        }
Exemple #25
0
        public void GenerateTwoBlocksInTwoRequests()
        {
            var crng    = CypherBasedPrngGenerator.Create(_ZeroKey32Bytes, outputBufferSize: 0);
            var buffer1 = new byte[crng.BlockSizeBytes * 2];
            var buffer2 = new byte[crng.BlockSizeBytes * 2];

            crng.FillWithRandomBytes(buffer1);
            crng.FillWithRandomBytes(buffer2);

            Assert.IsFalse(buffer1.All(b => b == 0));
            Assert.IsFalse(buffer2.All(b => b == 0));
            Assert.IsFalse(buffer1.SequenceEqual(buffer2));
            Assert.AreEqual(crng.BytesGenerated, buffer1.Length + buffer2.Length + 64);
            Assert.AreEqual(crng.BytesRequested, buffer1.Length + buffer2.Length);
        }
        public void RandomInt64_Fuzzing()
        {
            var prng = CypherBasedPrngGenerator.CreateWithCheapKey();

            // Dumps 100000 random int64s.
            using (var sw = new StreamWriter(nameof(RandomInt64_Fuzzing) + ".raw.txt", false, Encoding.UTF8))
            {
                for (int i = 0; i < 100000; i++)
                {
                    var theLong = prng.GetRandomInt64();
                    Assert.IsTrue(theLong >= 0 && theLong <= Int64.MaxValue);
                    sw.WriteLine(theLong);
                }
            }
        }
        public void RandomDecimal_Fuzzing()
        {
            var prng = CypherBasedPrngGenerator.CreateWithCheapKey();

            // Dumps 100000 random decimals.
            using (var sw = new StreamWriter(nameof(RandomDecimal_Fuzzing) + ".raw.txt", false, Encoding.UTF8))
            {
                for (int i = 0; i < 100000; i++)
                {
                    var theVal = prng.GetRandomDecimal();
                    Assert.IsTrue(theVal >= 0m && theVal < 1.0m, "Decimal: " + theVal + ", i: " + i);
                    sw.WriteLine(theVal);
                }
            }
        }
Exemple #28
0
        /// <summary>
        /// Creates a light weight PRNG from a Pooled Generator.
        /// If the Pooled Generator has not created its first seed, this will use the system crypto random to derive a seed.
        /// </summary>
        public static IRandomNumberGenerator CreateCypherBasedGeneratorOrUninitialised(this PooledEntropyCprngGenerator pooledRng)
        {
            if (pooledRng == null)
            {
                throw new ArgumentNullException(nameof(pooledRng));
            }

            if (pooledRng.ReseedCount > 0)
            {
                return(pooledRng.CreateCypherBasedGenerator());
            }
            else
            {
                return(CypherBasedPrngGenerator.CreateWithSystemCrngKey());
            }
        }
Exemple #29
0
        public void ReseedTakesEffectImmediately()
        {
            // As the PRNG uses buffering internally, there may be random bytes left over after a reseed.
            // Those left over bytes must be discarded.
            var crng1            = new CypherBasedPrngGenerator(_ZeroKey32Bytes);
            var crng2            = new CypherBasedPrngGenerator(_ZeroKey32Bytes);
            var preReseedResult1 = crng1.GetRandomBytes(64);
            var preReseedResult2 = crng2.GetRandomBytes(64);

            Assert.IsTrue(preReseedResult1.SequenceEqual(preReseedResult2));

            crng1.Reseed(_IncrementedKey32Bytes);
            var postReseedResult1 = crng1.GetRandomBytes(64);
            var postReseedResult2 = crng2.GetRandomBytes(64);

            Assert.IsFalse(postReseedResult1.SequenceEqual(postReseedResult2));
        }
        public void RandomInt32Distribution_ZeroTo47()
        {
            var prng = new CypherBasedPrngGenerator(new byte[32]);
            // Produces a histogram of 50000 random int32s in the range 0..47 and also writes the raw values out.
            var histogram = new int[47];

            using (var sw = new StreamWriter(nameof(RandomInt32Distribution_ZeroTo47) + ".raw.txt", false, Encoding.UTF8))
            {
                for (int i = 0; i < 50000; i++)
                {
                    var theInt = prng.GetRandomInt32(47);
                    Assert.IsTrue(theInt >= 0 && theInt < 47);
                    histogram[theInt] = histogram[theInt] + 1;
                    sw.WriteLine(theInt);
                }
            }
            WriteHistogramToTsv(histogram, nameof(RandomInt32Distribution_ZeroTo47) + ".txt");
        }