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); } }
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); }
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)); }
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)); }
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)); }
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)); }
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)); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
public void DifferentCounterAndCypherBlockSizeThrows() { Assert.ThrowsException <ArgumentOutOfRangeException>(() => new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256(), SHA256.Create(), new CypherCounter(32)) ); }
public void SmallerHashThanCypherKeySizeThrows() { Assert.ThrowsException <ArgumentOutOfRangeException>(() => new CypherBasedPrngGenerator(_ZeroKey32Bytes, CryptoPrimitive.Aes256(), MD5.Create(), new CypherCounter(16)) ); }
public void MismatchedKeyMaterialAndCypherKeySizeThrows() { Assert.ThrowsException <ArgumentOutOfRangeException>(() => new CypherBasedPrngGenerator(_ZeroKey16Bytes, CryptoPrimitive.Aes256Managed(), SHA256.Create(), new CypherCounter(16)) ); }
private static ICryptoPrimitive GetAes128CryptoPrimitive() => managedOrNativeCrypto == ManagedOrNative.Managed ? CryptoPrimitive.Aes128Managed() : managedOrNativeCrypto == ManagedOrNative.Native ? new BlockCypherCryptoPrimitive(new AesCryptoServiceProvider() { KeySize = 128 }) : CryptoPrimitive.Aes128();
private static ICryptoPrimitive GetSha512CryptoPrimitive() => managedOrNativeCrypto == ManagedOrNative.Managed ? CryptoPrimitive.Sha512Managed() : managedOrNativeCrypto == ManagedOrNative.Native ? new HashCryptoPrimitive(new SHA512CryptoServiceProvider()) : CryptoPrimitive.Sha512();