private void doExpectedTest(IDigest digest, int seed, byte[] expected, byte[] noCycle) { DigestRandomGenerator rGen = new DigestRandomGenerator(digest); byte[] output = new byte[digest.GetDigestSize()]; rGen.AddSeedMaterial(seed); for (int i = 0; i != 1024; i++) { rGen.NextBytes(output); } if (noCycle != null) { if (Arrays.AreEqual(noCycle, output)) { Fail("seed not being cycled!"); } } if (!Arrays.AreEqual(expected, output)) { Fail("expected output doesn't match"); } }
private void HandleAuthorizationRequest(AuthorizationRequestPacket packet) { if (IsInitialized) return; PlayerRef = new Trainer(packet.Name); SendPacket(new AuthorizationResponsePacket { AuthorizationStatus = AuthorizationStatus }); if (AuthorizationStatus.HasFlag(AuthorizationStatus.EncryprionEnabled)) { var publicKey = Module.RsaKeyPair.PublicKeyToByteArray(); VerificationToken = new byte[4]; var drg = new DigestRandomGenerator(new Sha512Digest()); drg.NextBytes(VerificationToken); SendPacket(new EncryptionRequestPacket {PublicKey = publicKey, VerificationToken = VerificationToken}); } else { if (!IsInitialized) { Join(); IsInitialized = true; } } }
public BufferedSecureRandom(byte[] password, int bufferSize = 1024) { this.bufferSize = bufferSize; this.buffer = new byte[bufferSize]; this.random = new DigestRandomGenerator(new Sha1Digest()); this.random.AddSeedMaterial(password); this.random.NextBytes(this.buffer); }
/// Generate a random nonce public static byte[] generateRandomNonce(int length, int bit = 256) { DigestRandomGenerator wkRandomGenerator = new Org.BouncyCastle.Crypto.Prng.DigestRandomGenerator(new Sha512Digest()); SecureRandom secureRandomGenerator = new SecureRandom(wkRandomGenerator); List <byte> wkNonce = new List <byte>(); for (int i = 0; i < length; i++) { wkNonce.Add((byte)secureRandomGenerator.Next(0, bit)); } byte[] nonce = wkNonce.ToArray(); return(nonce); }
/// Generates a SecureRandom /// C# has not a fortuna random generator, Just trying an approach with DigestRandomGenerator from BouncyCastle public static SecureRandom getSecureRandom() { // Start from a crypto seed from C# libraries System.Security.Cryptography.RNGCryptoServiceProvider rngCsp = new System.Security.Cryptography.RNGCryptoServiceProvider(); byte[] randomBytes = new byte[32]; rngCsp.GetBytes(randomBytes); // Get a frist random generator from BouncyCastle VmpcRandomGenerator firstRandomGenerator = new Org.BouncyCastle.Crypto.Prng.VmpcRandomGenerator(); firstRandomGenerator.AddSeedMaterial(randomBytes); byte[] seed = new byte[32]; firstRandomGenerator.NextBytes(seed, 0, 32); // Create and seed the final Randon Generator DigestRandomGenerator wkRandomGenerator = new Org.BouncyCastle.Crypto.Prng.DigestRandomGenerator(new Sha512Digest()); SecureRandom secureRandomGenerator = new SecureRandom(wkRandomGenerator); secureRandomGenerator.SetSeed(seed); return(secureRandomGenerator); }
public TinHatURandom(TinHatRandom myTinHatRandom, IDigest digest) { this.myTinHatRandom = myTinHatRandom; this.myTinHatRandom_IsMineExclusively = false; this.myPrng = new DigestRandomGenerator(digest); this.digestSize = digest.GetDigestSize(); this.SeedSize = this.digestSize; Reseed(); }
public TinHatURandom(List<SupportingClasses.EntropyHasher> EntropyHashers, IDigest digest) { this.myTinHatRandom = new TinHatRandom(EntropyHashers); this.myTinHatRandom_IsMineExclusively = true; this.myPrng = new DigestRandomGenerator(digest); this.digestSize = digest.GetDigestSize(); this.SeedSize = this.digestSize; Reseed(); }
/* BouncyCastle DigestRandomGenerator Analysis * BouncyCastle DigestRandomGenerator maintains two separate but related internal states, represented by the following: * byte[] seed * long seedCounter * byte[] state * long stateCounter * The size of seed and state are both equal to the size of the digest. I am going to refer to the digest size, in bits, * as "M". The counters are obviously 64 bits each. * * In order to generate repeated output, there would need to be a collision of stateCounter, state, and seed. We expect a seed * collision every 2^(M/2) times that we cycle seed. We expect a state collision every 2^(M/2) times that we GenerateState, * and stateCounter will repeat itself every 2^64 times that we call GenerateState. This means we can never have a repeated * stateCounter&state&seed in less than 2^64 calls to GenerateState, and very likely, it would be much much larger than that. * * GenerateState is called at least once for every call to NextBytes, and it's called more times, if the number of bytes reqested * >= digest size in bytes. We can easily measure the number of calls to GenerateState, by counting 1+(bytes.Length/digest.Size), * and we want to ensure this number is always below 2^64, which is UInt64.MaxValue * * bytes.Length is an Int32. We can easily guarantee we'll never repeat an internal state, if we use a UInt64 to tally the * number of calls to GenerateState, and require new seed material before UInt64.MaxValue - Int32.MaxValue. This is a huge number. * * To put this in perspective, supposing a 128 bit digest, and supposing the user on average requests 8 bytes per call to NextBytes. * Then there is guaranteed to be no repeat state before 147 quintillion bytes (147 billion billion). So let's just tone this * down a bit, and choose thresholds that are way more conservative. * * Completely unrelated to analysis of DigestRandomGenerator, some other prng's (fortuna) recommend new seed material in 2^20 * iterations, due to limitations they have, which we don't have. So let's just ensure we end up choosing thresholds that are down * on-par with that level, even though completely unnecessary for us, it will feel conservative and safe. * * Let's use a plain old int to tally the number of calls to GenerateState. We need to ensure we never overflow this counter, so * let's assume all digests are at least 4 bytes, and let's require new seed material every int.MaxValue/2. This is basically * 1 billion calls to NextBytes, so a few GB of random data or so. Extremely safe and conservative. * * But let's squish it down even more than that. TinHatURandom performs approx 1,000 times faster than TinHatRandom. So to * maximize the sweet spot between strong security and good performance, let's only stretch the entropy 1,000,000 times at hard * maximum, and 64,000 times softly suggested. Typically, for example with Sha256, this means we'll generate up to 2MB before * requesting reseed, and up to 32MB before requiring reseed. * * Now we're super duper conservative, being zillions of times more conservative than necessary, maximally conservative to the point * where we do not take an appreciable performance degradation. */ public TinHatURandom() { this.myTinHatRandom = new TinHatRandom(); this.myTinHatRandom_IsMineExclusively = true; IDigest digest = new Sha512Digest(); this.myPrng = new DigestRandomGenerator(digest); this.digestSize = digest.GetDigestSize(); this.SeedSize = this.digestSize; Reseed(); }
public DTLSContext(bool client, Version version, HandshakeInfo handshakeInfo) { IsServer = !client; if (version == DTLSRecord.Version1_2) { ClientVersion = ProtocolVersion.DTLSv12; ServerVersion = ProtocolVersion.DTLSv12; } else { ClientVersion = ProtocolVersion.DTLSv10; ServerVersion = ProtocolVersion.DTLSv10; } SecurityParameters = new DTLSSecurityParameters(version, handshakeInfo); NonceRandomGenerator = new DigestRandomGenerator(TlsUtilities.CreateHash(HashAlgorithm.sha256)); NonceRandomGenerator.AddSeedMaterial(Times.NanoTime()); }
private void doCountTest(IDigest digest, byte[] seed, byte[] expectedXors) { DigestRandomGenerator rGen = new DigestRandomGenerator(digest); byte[] output = new byte[digest.GetDigestSize()]; int[] averages = new int[digest.GetDigestSize()]; byte[] ands = new byte[digest.GetDigestSize()]; byte[] xors = new byte[digest.GetDigestSize()]; byte[] ors = new byte[digest.GetDigestSize()]; rGen.AddSeedMaterial(seed); for (int i = 0; i != 1000000; i++) { rGen.NextBytes(output); for (int j = 0; j != output.Length; j++) { averages[j] += output[j] & 0xff; ands[j] &= output[j]; xors[j] ^= output[j]; ors[j] |= output[j]; } } for (int i = 0; i != output.Length; i++) { if ((averages[i] / 1000000) != 127) { Fail("average test failed for " + digest.AlgorithmName); } if (ands[i] != 0) { Fail("and test failed for " + digest.AlgorithmName); } if ((ors[i] & 0xff) != 0xff) { Fail("or test failed for " + digest.AlgorithmName); } if (xors[i] != expectedXors[i]) { Fail("xor test failed for " + digest.AlgorithmName); } } }
/// <summary> /// Note: Clears pool contents before returning /// </summary> private void CreateNewPRNG(byte[] pool) { if (pool == null) { throw new CryptographicException("Refusing to reseed with null pool"); } try { if (pool.Length != PoolSize) { throw new CryptographicException("Refusing to reseed with invalid pool"); } // Now, pool has been seeded, file operations are all completed, it's time to create my internal PRNG IDigest digest; switch (this.myRNGAlgorithm) { case PrngAlgorithm.MD5_128bit: digest = new MD5Digest(); break; case PrngAlgorithm.RIPEMD128_128bit: digest = new RipeMD128Digest(); break; case PrngAlgorithm.RIPEMD160_160bit: digest = new RipeMD160Digest(); break; case PrngAlgorithm.RIPEMD256_256bit: digest = new RipeMD256Digest(); break; case PrngAlgorithm.RIPEMD320_320bit: digest = new RipeMD320Digest(); break; case PrngAlgorithm.SHA1_160bit: digest = new Sha1Digest(); break; case PrngAlgorithm.SHA256_256bit: digest = new Sha256Digest(); break; case PrngAlgorithm.SHA512_512bit: digest = new Sha512Digest(); break; case PrngAlgorithm.Tiger_192bit: digest = new TigerDigest(); break; case PrngAlgorithm.Whirlpool_512bit: digest = new WhirlpoolDigest(); break; default: throw new CryptographicException("Unknown prngAlgorithm specified: " + this.myRNGAlgorithm.ToString()); } var drng = new DigestRandomGenerator(digest); drng.AddSeedMaterial(pool); this.myRNG = drng; } finally { Array.Clear(pool, 0, pool.Length); } }