Example #1
0
        private static ICryptoPrimitive GetCryptoPrimitive()
        {
            if (cryptoPrimitive == CryptoPrimitiveOption.Default || cryptoPrimitive == CryptoPrimitiveOption.Aes256)
            {
                return(GetAes256CryptoPrimitive());
            }
            else if (cryptoPrimitive == CryptoPrimitiveOption.Aes128)
            {
                return(GetAes128CryptoPrimitive());
            }

            else if (cryptoPrimitive == CryptoPrimitiveOption.Sha256)
            {
                return(GetSha256CryptoPrimitive());
            }
            else if (cryptoPrimitive == CryptoPrimitiveOption.Sha512)
            {
                return(GetSha512CryptoPrimitive());
            }

            else if (cryptoPrimitive == CryptoPrimitiveOption.HmacSha256)
            {
                return(CryptoPrimitive.HmacSha256());
            }
            else if (cryptoPrimitive == CryptoPrimitiveOption.HmacSha512)
            {
                return(CryptoPrimitive.HmacSha512());
            }

            else
            {
                throw new Exception("Unknown crypto primitive: " + cryptoPrimitive);
            }
        }
Example #2
0
        public void ConstructAesManagedCrng()
        {
            var crng = new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256Managed(), SHA256.Create(), new CypherCounter(16));

            // Creating a generator should not actually generate any bytes.
            Assert.AreEqual(crng.BytesGenerated, 0L);
            Assert.AreEqual(crng.BytesRequested, 0L);
        }
Example #3
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));
        }
Example #4
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));
        }
Example #5
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));
        }
Example #6
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));
        }
Example #7
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));
        }
Example #8
0
        public void GenerateSingleBlockAesManaged()
        {
            var crng   = new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256Managed(), 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);
        }
Example #9
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);
        }
Example #10
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);
        }
Example #11
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);
        }
Example #12
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);
        }
Example #13
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);
        }
Example #14
0
        private static GeneratorAndDescription CreateRandomGenerator()
        {
            var result = new GeneratorAndDescription();

            if (generatorType == Generator.StockRandom)
            {
                result.Description             = "deterministic PRNG - " + typeof(Rand).Namespace + "." + typeof(Rand).Name;
                var(seed, description)         = DeriveSeed();
                result.SeedDescription         = description;
                result.Generator               = new StandardRandomWrapperGenerator(new Rand(BitConverter.ToInt32(seed, 0)));
                result.WaitForGeneratorReady   = () => { };
                result.WaitForGeneratorStopped = () => { };
            }
            else if (generatorType == Generator.CryptoRandom)
            {
                result.Description             = "non-deterministic CPRNG - " + typeof(RandomNumberGenerator).Namespace + "." + typeof(RandomNumberGenerator).Name;
                result.SeedDescription         = "No seed required";
                result.Generator               = new CryptoRandomWrapperGenerator();
                result.WaitForGeneratorReady   = () => { };
                result.WaitForGeneratorStopped = () => { };
            }
            else if (generatorType == Generator.TerningerCypher)
            {
                var primitive     = GetCryptoPrimitive();
                var hash          = GetHashAlgorithm();
                var counter       = new CypherCounter(primitive.BlockSizeBytes);
                var entropyGetter = GetEntropyGetter();
                var(seed, description)         = DeriveSeed();
                result.Description             = $"{(nonDeterministic ? "non-" : "")}deterministic PRNG - " + typeof(CypherBasedPrngGenerator).Namespace + "." + typeof(CypherBasedPrngGenerator).Name;
                result.ExtraDescription        = $"Using crypto primitive: {cryptoPrimitive}, hash: {hashAlgorithm}";
                result.SeedDescription         = description;
                result.Generator               = CypherBasedPrngGenerator.Create(key: seed, cryptoPrimitive: primitive, hashAlgorithm: hash, initialCounter: counter, additionalEntropyGetter: entropyGetter);
                result.WaitForGeneratorReady   = () => { };
                result.WaitForGeneratorStopped = () => { };
            }
            else if (generatorType == Generator.TerningerPooled)
            {
                var(seed, description) = DeriveSeed();
                result.SeedDescription = description;

                // Accumulator.
                var accKey = SHA512.Create().ComputeHash(
                    StaticLocalEntropy.Get32().GetAwaiter().GetResult().Concat(CheapEntropy.Get32()).ToArray()
                    ).EnsureArraySize(32);
                var accPrng = CypherBasedPrngGenerator.Create(accKey, CryptoPrimitive.Aes256(), SHA512.Create());
                var acc     = new EntropyAccumulator(linearPools, randomPools, accPrng, SHA512.Create);

                // Generator.
                var primitive = GetCryptoPrimitive();
                var hash      = GetHashAlgorithm();
                var genPrng   = CypherBasedPrngGenerator.Create(new byte[32], primitive, hash);
                IEnumerable <IEntropySource> sources = new IEntropySource[] {
                    new UserSuppliedSource(seed),
                    new CurrentTimeSource(),
                    new TimerSource(),
                    new GCMemorySource(),
                    new CryptoRandomSource(),
                    new NetworkStatsSource(),
                    new ProcessStatsSource(),
                };
                if (includeNetworkSources)
                {
                    sources = sources.Concat(new IEntropySource[] {
                        new PingStatsSource(),
                        new ExternalWebContentSource(),
                        new AnuExternalRandomSource(),
                        new BeaconNistExternalRandomSource(),
                        new HotbitsExternalRandomSource(),
                        new RandomNumbersInfoExternalRandomSource(),
                        new RandomOrgExternalRandomSource(),
                    });
                }
                // As the pooled generator will be churning out entropy as fast as it can, we increase the reseed rate by polling faster and forcing reseeds more frequently.
                var config = new PooledEntropyCprngGenerator.PooledGeneratorConfig()
                {
                    MaximumBytesGeneratedBeforeReseed      = Int32.MaxValue,
                    PollWaitTimeInNormalPriority           = TimeSpan.FromSeconds(1),
                    EntropyToTriggerReseedInNormalPriority = 64,
                };
                var generator = new PooledEntropyCprngGenerator(sources, acc, genPrng, config);
                result.Generator             = generator;
                result.Description           = $"non-deterministic CPRNG - " + typeof(PooledEntropyCprngGenerator).Namespace + "." + typeof(PooledEntropyCprngGenerator).Name;
                result.ExtraDescription      = $"Using {linearPools}+{randomPools} pools (linear+random), {sources.Count()} entropy sources, crypto primitive: {cryptoPrimitive}, hash: {hashAlgorithm}";
                result.WaitForGeneratorReady = () => {
                    generator.StartAndWaitForFirstSeed().Wait(TimeSpan.FromSeconds(60));
                };
                result.WaitForGeneratorStopped = () => {
                    generator.Stop().Wait(TimeSpan.FromSeconds(60));
                };
            }
            else
            {
                throw new Exception("Unexpected Generator type: " + generatorType);
            }
            return(result);
        }
Example #15
0
 public void DifferentCounterAndCypherBlockSizeThrows()
 {
     Assert.ThrowsException <ArgumentOutOfRangeException>(() =>
                                                          new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256(), SHA256.Create(), new CypherCounter(32))
                                                          );
 }
Example #16
0
 public void SmallerHashThanCypherKeySizeThrows()
 {
     Assert.ThrowsException <ArgumentOutOfRangeException>(() =>
                                                          new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256(), MD5.Create(), new CypherCounter(16))
                                                          );
 }
Example #17
0
 public void MismatchedKeyMaterialAndCypherKeySizeThrows()
 {
     Assert.ThrowsException <ArgumentOutOfRangeException>(() =>
                                                          new CypherBasedPrngGenerator(_ZeroKey16Bytes, CryptoPrimitive.Aes256Managed(), SHA256.Create(), new CypherCounter(16))
                                                          );
 }
Example #18
0
 private static ICryptoPrimitive GetAes128CryptoPrimitive() => managedOrNativeCrypto == ManagedOrNative.Managed ? CryptoPrimitive.Aes128Managed()
                                                             : managedOrNativeCrypto == ManagedOrNative.Native ? new BlockCypherCryptoPrimitive(new AesCryptoServiceProvider()
 {
     KeySize = 128
 })
                                                             : CryptoPrimitive.Aes128();
Example #19
0
 private static ICryptoPrimitive GetSha512CryptoPrimitive() => managedOrNativeCrypto == ManagedOrNative.Managed ? CryptoPrimitive.Sha512Managed()
                                                             : managedOrNativeCrypto == ManagedOrNative.Native ? new HashCryptoPrimitive(new SHA512CryptoServiceProvider())
                                                             : CryptoPrimitive.Sha512();