private byte[] GenerateRandom256() { if (this.GenerateRandom256Pre != null) { this.GenerateRandom256Pre(this, EventArgs.Empty); } byte[] pbCmp; lock (m_oSyncRoot) { m_uCounter += 0x74D8B29E4D38E161UL; // Prime number byte[] pbCounter = MemUtil.UInt64ToBytes(m_uCounter); byte[] pbCsp = GetCspRandom(); byte[] pbPool = m_pbEntropyPool.ReadData(); int cbPool = pbPool.Length; int cbCtr = pbCounter.Length; int cbCsp = pbCsp.Length; pbCmp = new byte[cbPool + cbCtr + cbCsp]; Array.Copy(pbPool, pbCmp, cbPool); Array.Copy(pbCounter, 0, pbCmp, cbPool, cbCtr); Array.Copy(pbCsp, 0, pbCmp, cbPool + cbCtr, cbCsp); MemUtil.ZeroByteArray(pbCsp); MemUtil.ZeroByteArray(pbPool); m_uGeneratedBytesCount += 32; } byte[] pbRet = CryptoUtil.HashSha256(pbCmp); MemUtil.ZeroByteArray(pbCmp); return(pbRet); }
private static void AddStrHash(Stream s, string str) { if (s == null) { Debug.Assert(false); return; } if (string.IsNullOrEmpty(str)) { return; } byte[] pbUtf8 = StrUtil.Utf8.GetBytes(str); byte[] pbHash = CryptoUtil.HashSha256(pbUtf8); MemUtil.Write(s, pbHash); }
/// <summary> /// Construct a new cryptographically secure random stream object. /// </summary> /// <param name="a">Algorithm to use.</param> /// <param name="pbKey">Initialization key. Must not be <c>null</c> /// and must contain at least 1 byte.</param> public CryptoRandomStream(CrsAlgorithm a, byte[] pbKey) { if (pbKey == null) { Debug.Assert(false); throw new ArgumentNullException("pbKey"); } int cbKey = pbKey.Length; if (cbKey <= 0) { Debug.Assert(false); // Need at least one byte throw new ArgumentOutOfRangeException("pbKey"); } m_crsAlgorithm = a; if (a == CrsAlgorithm.ChaCha20) { byte[] pbKey32 = new byte[32]; byte[] pbIV12 = new byte[12]; using (SHA512Managed h = new SHA512Managed()) { byte[] pbHash = h.ComputeHash(pbKey); Array.Copy(pbHash, pbKey32, 32); Array.Copy(pbHash, 32, pbIV12, 0, 12); MemUtil.ZeroByteArray(pbHash); } m_chacha20 = new ChaCha20Cipher(pbKey32, pbIV12, true); } else if (a == CrsAlgorithm.Salsa20) { byte[] pbKey32 = CryptoUtil.HashSha256(pbKey); byte[] pbIV8 = new byte[8] { 0xE8, 0x30, 0x09, 0x4B, 0x97, 0x20, 0x5D, 0x2A }; // Unique constant m_salsa20 = new Salsa20Cipher(pbKey32, pbIV8); } else if (a == CrsAlgorithm.ArcFourVariant) { // Fill the state linearly m_pbState = new byte[256]; for (int w = 0; w < 256; ++w) { m_pbState[w] = (byte)w; } unchecked { byte j = 0, t; int inxKey = 0; for (int w = 0; w < 256; ++w) // Key setup { j += (byte)(m_pbState[w] + pbKey[inxKey]); t = m_pbState[0]; // Swap entries m_pbState[0] = m_pbState[j]; m_pbState[j] = t; ++inxKey; if (inxKey >= cbKey) { inxKey = 0; } } } GetRandomBytes(512); // Increases security, see cryptanalysis } else // Unknown algorithm { Debug.Assert(false); throw new ArgumentOutOfRangeException("a"); } }