/// <summary> /// Construct a new cryptographically secure random stream object. /// </summary> /// <param name="genAlgorithm">Algorithm to use.</param> /// <param name="pbKey">Initialization key. Must not be <c>null</c> and /// must contain at least 1 byte.</param> /// <exception cref="System.ArgumentNullException">Thrown if the /// <paramref name="pbKey" /> parameter is <c>null</c>.</exception> /// <exception cref="System.ArgumentException">Thrown if the /// <paramref name="pbKey" /> parameter contains no bytes or the /// algorithm is unknown.</exception> public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey) { m_crsAlgorithm = genAlgorithm; Debug.Assert(pbKey != null); if(pbKey == null) throw new ArgumentNullException("pbKey"); uint uKeyLen = (uint)pbKey.Length; Debug.Assert(uKeyLen != 0); if(uKeyLen == 0) throw new ArgumentException(); if(genAlgorithm == CrsAlgorithm.ArcFourVariant) { m_pbState = ComputeArcFourState(pbKey, uKeyLen); GetRandomBytes(512); // Increases security, see cryptanalysis } else if(genAlgorithm == CrsAlgorithm.Salsa20) { SHA256Managed sha256 = new SHA256Managed(); byte[] pbKey32 = sha256.ComputeHash(pbKey); byte[] pbIV = new byte[]{ 0xE8, 0x30, 0x09, 0x4B, 0x97, 0x20, 0x5D, 0x2A }; // Unique constant m_salsa20 = new Salsa20Cipher(pbKey32, pbIV); } else // Unknown algorithm { Debug.Assert(false); throw new ArgumentException(); } }
/// <summary> /// Construct a new cryptographically secure random stream object. /// </summary> /// <param name="genAlgorithm">Algorithm to use.</param> /// <param name="pbKey">Initialization key. Must not be <c>null</c> and /// must contain at least 1 byte.</param> /// <exception cref="System.ArgumentNullException">Thrown if the /// <paramref name="pbKey" /> parameter is <c>null</c>.</exception> /// <exception cref="System.ArgumentException">Thrown if the /// <paramref name="pbKey" /> parameter contains no bytes or the /// algorithm is unknown.</exception> public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey) { if (pbKey == null) throw new ArgumentNullException("pbKey"); _algorithm = genAlgorithm; var uKeyLen = (uint)pbKey.Length; if (uKeyLen == 0) throw new ArgumentException(); switch (genAlgorithm) { case CrsAlgorithm.ArcFourVariant: _pbState = new byte[256]; for (uint w = 0; w < 256; ++w) _pbState[w] = (byte)w; unchecked { byte j = 0, t; uint inxKey = 0; for (uint w = 0; w < 256; ++w) // Key setup { j += (byte)(_pbState[w] + pbKey[inxKey]); t = _pbState[0]; // Swap entries _pbState[0] = _pbState[j]; _pbState[j] = t; ++inxKey; if (inxKey >= uKeyLen) inxKey = 0; } } GetRandomBytes(512); // Increases security, see cryptanalysis break; case CrsAlgorithm.Salsa20: { var sha256 = new SHA256Managed(); var pbKey32 = sha256.ComputeHash(pbKey); var pbIV = new byte[] { 0xE8, 0x30, 0x09, 0x4B, 0x97, 0x20, 0x5D, 0x2A }; // Unique constant _salsa20 = new Salsa20Cipher(pbKey32, pbIV); } break; default: throw new ArgumentException(); } }
/// <summary> /// Construct a new cryptographically secure random stream object. /// </summary> /// <param name="genAlgorithm">Algorithm to use.</param> /// <param name="pbKey">Initialization key. Must not be <c>null</c> and /// must contain at least 1 byte.</param> /// <exception cref="System.ArgumentNullException">Thrown if the /// <paramref name="pbKey" /> parameter is <c>null</c>.</exception> /// <exception cref="System.ArgumentException">Thrown if the /// <paramref name="pbKey" /> parameter contains no bytes or the /// algorithm is unknown.</exception> public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey, ICanSHA256Hash hasher) { _hasher = hasher; m_crsAlgorithm = genAlgorithm; uint uKeyLen = (uint)pbKey.Length; if (genAlgorithm == CrsAlgorithm.ArcFourVariant) { // Fill the state linearly m_pbState = new byte[256]; for (uint w = 0; w < 256; ++w) m_pbState[w] = (byte)w; unchecked { byte j = 0, t; uint inxKey = 0; for (uint 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 >= uKeyLen) inxKey = 0; } } GetRandomBytes(512); // Increases security, see cryptanalysis } else if (genAlgorithm == CrsAlgorithm.Salsa20) { byte[] pbKey32 = _hasher.Hash(pbKey); byte[] pbIV = new byte[]{ 0xE8, 0x30, 0x09, 0x4B, 0x97, 0x20, 0x5D, 0x2A }; // Unique constant m_salsa20 = new Salsa20Cipher(pbKey32, pbIV); } else // Unknown algorithm { throw new UnknownAlgorithmException(); } }
/// <summary> /// Construct a new cryptographically secure random stream object. /// </summary> /// <param name="genAlgorithm">Algorithm to use.</param> /// <param name="pbKey">Initialization key. Must not be <c>null</c> and /// must contain at least 1 byte.</param> /// <exception cref="System.ArgumentNullException">Thrown if the /// <paramref name="pbKey" /> parameter is <c>null</c>.</exception> /// <exception cref="System.ArgumentException">Thrown if the /// <paramref name="pbKey" /> parameter contains no bytes or the /// algorithm is unknown.</exception> public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey) { m_crsAlgorithm = genAlgorithm; Debug.Assert(pbKey != null); if (pbKey == null) { throw new ArgumentNullException("pbKey"); } uint uKeyLen = (uint)pbKey.Length; Debug.Assert(uKeyLen != 0); if (uKeyLen == 0) { throw new ArgumentException(); } if (genAlgorithm == CrsAlgorithm.ArcFour) { uint w, inxKey = 0; // Fill the state linearly for (w = 0; w < 256; ++w) { m_pbState[w] = (byte)w; } byte i = 0, j = 0, t; for (w = 0; w < 256; ++w) // Key setup { j += (byte)(m_pbState[w] + pbKey[inxKey]); t = m_pbState[i]; // Swap entries m_pbState[i] = m_pbState[j]; m_pbState[j] = t; ++inxKey; if (inxKey >= uKeyLen) { inxKey = 0; } } this.GetRandomBytes(512); // Throw away the first bytes } else // Unknown algorithm { Debug.Assert(false); throw new ArgumentException(); } }
/// <summary> /// Construct a new cryptographically secure random stream object. /// </summary> /// <param name="genAlgorithm">Algorithm to use.</param> /// <param name="pbKey">Initialization key. Must not be <c>null</c> and /// must contain at least 1 byte.</param> /// <exception cref="System.ArgumentNullException">Thrown if the /// <paramref name="pbKey" /> parameter is <c>null</c>.</exception> /// <exception cref="System.ArgumentException">Thrown if the /// <paramref name="pbKey" /> parameter contains no bytes or the /// algorithm is unknown.</exception> public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey) { m_crsAlgorithm = genAlgorithm; Debug.Assert(pbKey != null); if(pbKey == null) throw new ArgumentNullException("pbKey"); uint uKeyLen = (uint)pbKey.Length; Debug.Assert(uKeyLen != 0); if(uKeyLen == 0) throw new ArgumentException(); if(genAlgorithm == CrsAlgorithm.ArcFourVariant) { // Fill the state linearly m_pbState = new byte[256]; for(uint w = 0; w < 256; ++w) m_pbState[w] = (byte)w; unchecked { byte j = 0, t; uint inxKey = 0; for(uint 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 >= uKeyLen) inxKey = 0; } } GetRandomBytes(512); // Increases security, see cryptanalysis } else if(genAlgorithm == CrsAlgorithm.Salsa20) { SHA256Managed sha256 = new SHA256Managed(); byte[] pbKey32 = sha256.ComputeHash(pbKey); byte[] pbIV = new byte[]{ 0xE8, 0x30, 0x09, 0x4B, 0x97, 0x20, 0x5D, 0x2A }; // Unique constant m_salsa20 = new Salsa20Cipher(pbKey32, pbIV); } else // Unknown algorithm { Debug.Assert(false); throw new ArgumentException(); } }
private static int BenchTime(CrsAlgorithm cra, int nRounds, int nDataSize) { byte[] pbKey = new byte[4] { 0x00, 0x01, 0x02, 0x03 }; int nStart = Environment.TickCount; for (int i = 0; i < nRounds; ++i) { CryptoRandomStream c = new CryptoRandomStream(cra, pbKey); c.GetRandomBytes((uint)nDataSize); } int nEnd = Environment.TickCount; return(nEnd - nStart); }
/// <summary> /// Construct a new cryptographically secure random stream object. /// </summary> /// <param name="genAlgorithm">Algorithm to use.</param> /// <param name="pbKey">Initialization key. Must not be <c>null</c> and /// must contain at least 1 byte.</param> /// <exception cref="System.ArgumentNullException">Thrown if the /// <paramref name="pbKey" /> parameter is <c>null</c>.</exception> /// <exception cref="System.ArgumentException">Thrown if the /// <paramref name="pbKey" /> parameter contains no bytes or the /// algorithm is unknown.</exception> public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey) { m_crsAlgorithm = genAlgorithm; Debug.Assert(pbKey != null); if (pbKey == null) { throw new ArgumentNullException("pbKey"); } uint uKeyLen = (uint)pbKey.Length; Debug.Assert(uKeyLen != 0); if (uKeyLen == 0) { throw new ArgumentException(); } if (genAlgorithm == CrsAlgorithm.ArcFourVariant) { m_pbState = ComputeArcFourState(pbKey, uKeyLen); GetRandomBytes(512); // Increases security, see cryptanalysis } else if (genAlgorithm == CrsAlgorithm.Salsa20) { SHA256Managed sha256 = new SHA256Managed(); byte[] pbKey32 = sha256.ComputeHash(pbKey); byte[] pbIV = new byte[] { 0xE8, 0x30, 0x09, 0x4B, 0x97, 0x20, 0x5D, 0x2A }; // Unique constant m_salsa20 = new Salsa20Cipher(pbKey32, pbIV); } else // Unknown algorithm { Debug.Assert(false); throw new ArgumentException(); } }
/// <summary> /// Construct a new cryptographically secure random stream object. /// </summary> /// <param name="genAlgorithm">Algorithm to use.</param> /// <param name="pbKey">Initialization key. Must not be <c>null</c> and /// must contain at least 1 byte.</param> /// <exception cref="System.ArgumentNullException">Thrown if the /// <paramref name="pbKey" /> parameter is <c>null</c>.</exception> /// <exception cref="System.ArgumentException">Thrown if the /// <paramref name="pbKey" /> parameter contains no bytes or the /// algorithm is unknown.</exception> public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey) { m_crsAlgorithm = genAlgorithm; Debug.Assert(pbKey != null); if(pbKey == null) throw new ArgumentNullException("pbKey"); uint uKeyLen = (uint)pbKey.Length; Debug.Assert(uKeyLen != 0); if(uKeyLen == 0) throw new ArgumentException(); if(genAlgorithm == CrsAlgorithm.ArcFour) { uint w, inxKey = 0; // Fill the state linearly for(w = 0; w < 256; ++w) m_pbState[w] = (byte)w; byte i = 0, j = 0, t; for(w = 0; w < 256; ++w) // Key setup { j += (byte)(m_pbState[w] + pbKey[inxKey]); t = m_pbState[i]; // Swap entries m_pbState[i] = m_pbState[j]; m_pbState[j] = t; ++inxKey; if(inxKey >= uKeyLen) inxKey = 0; } this.GetRandomBytes(512); // Throw away the first bytes } else // Unknown algorithm { Debug.Assert(false); throw new ArgumentException(); } }
/// <summary> /// Construct a new cryptographically secure random stream object. /// </summary> /// <param name="genAlgorithm">Algorithm to use.</param> /// <param name="pbKey">Initialization key. Must not be <c>null</c> and /// must contain at least 1 byte.</param> /// <exception cref="System.ArgumentNullException">Thrown if the /// <paramref name="pbKey" /> parameter is <c>null</c>.</exception> /// <exception cref="System.ArgumentException">Thrown if the /// <paramref name="pbKey" /> parameter contains no bytes or the /// algorithm is unknown.</exception> public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey) { m_crsAlgorithm = genAlgorithm; Debug.Assert(pbKey != null); if (pbKey == null) { throw new ArgumentNullException("pbKey"); } uint uKeyLen = (uint)pbKey.Length; Debug.Assert(uKeyLen != 0); if (uKeyLen == 0) { throw new ArgumentException(); } if (genAlgorithm == CrsAlgorithm.ArcFourVariant) { // Fill the state linearly m_pbState = new byte[256]; for (uint w = 0; w < 256; ++w) { m_pbState[w] = (byte)w; } unchecked { byte j = 0, t; uint inxKey = 0; for (uint 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 >= uKeyLen) { inxKey = 0; } } } GetRandomBytes(512); // Increases security, see cryptanalysis } else if (genAlgorithm == CrsAlgorithm.Salsa20) { SHA256Managed sha256 = new SHA256Managed(); byte[] pbKey32 = sha256.ComputeHash(pbKey); byte[] pbIV = new byte[] { 0xE8, 0x30, 0x09, 0x4B, 0x97, 0x20, 0x5D, 0x2A }; // Unique constant m_salsa20 = new Salsa20Cipher(pbKey32, pbIV); } else // Unknown algorithm { Debug.Assert(false); throw new ArgumentException(); } }
private static int BenchTime(CrsAlgorithm cra, int nRounds, int nDataSize) { byte[] pbKey = new byte[4] { 0x00, 0x01, 0x02, 0x03 }; int nStart = Environment.TickCount; for(int i = 0; i < nRounds; ++i) { CryptoRandomStream c = new CryptoRandomStream(cra, pbKey); c.GetRandomBytes((uint)nDataSize); } int nEnd = Environment.TickCount; return (nEnd - nStart); }
/// <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"); } }
/// <summary> /// Initializes a new instance of the <see cref="CryptoRandomStream"/> class. /// Construct a new cryptographically secure random stream object. /// </summary> /// <param name="genAlgorithm"> /// Algorithm to use. /// </param> /// <param name="pbKey"> /// Initialization key. Must not be <c>null</c> and /// must contain at least 1 byte. /// </param> /// <exception cref="System.ArgumentNullException"> /// Thrown if the /// <paramref name="pbKey"/> parameter is <c>null</c>. /// </exception> /// <exception cref="System.ArgumentException"> /// Thrown if the /// <paramref name="pbKey"/> parameter contains no bytes or the /// algorithm is unknown. /// </exception> public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey) { this.m_crsAlgorithm = genAlgorithm; Debug.Assert(pbKey != null); if (pbKey == null) { throw new ArgumentNullException("pbKey"); } uint uKeyLen = (uint)pbKey.Length; Debug.Assert(uKeyLen != 0); if (uKeyLen == 0) { throw new ArgumentException(); } if (genAlgorithm == CrsAlgorithm.ArcFourVariant) { // Fill the state linearly this.m_pbState = new byte[256]; for (uint w = 0; w < 256; ++w) { this.m_pbState[w] = (byte)w; } unchecked { byte j = 0, t; uint inxKey = 0; for (uint w = 0; w < 256; ++w) { // Key setup j += (byte)(this.m_pbState[w] + pbKey[inxKey]); t = this.m_pbState[0]; // Swap entries this.m_pbState[0] = this.m_pbState[j]; this.m_pbState[j] = t; ++inxKey; if (inxKey >= uKeyLen) { inxKey = 0; } } } this.GetRandomBytes(512); // Increases security, see cryptanalysis } else if (genAlgorithm == CrsAlgorithm.Salsa20) { var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256); byte[] pbKey32 = sha256.HashData(pbKey.AsBuffer()).ToArray(); byte[] pbIV = new byte[] { 0xE8, 0x30, 0x09, 0x4B, 0x97, 0x20, 0x5D, 0x2A }; // Unique constant this.m_salsa20 = new Salsa20Cipher(pbKey32, pbIV); } else { // Unknown algorithm Debug.Assert(false); throw new ArgumentException(); } }
/// <summary> /// Construct a new cryptographically secure random stream object. /// </summary> /// <param name="genAlgorithm">Algorithm to use.</param> /// <param name="pbKey">Initialization key. Must not be <c>null</c> and /// must contain at least 1 byte.</param> /// <exception cref="System.ArgumentNullException">Thrown if the /// <paramref name="pbKey" /> parameter is <c>null</c>.</exception> /// <exception cref="System.ArgumentException">Thrown if the /// <paramref name="pbKey" /> parameter contains no bytes or the /// algorithm is unknown.</exception> public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey) { if (pbKey == null) { throw new ArgumentNullException("pbKey"); } _algorithm = genAlgorithm; var uKeyLen = (uint)pbKey.Length; if (uKeyLen == 0) { throw new ArgumentException(); } switch (genAlgorithm) { case CrsAlgorithm.ArcFourVariant: _pbState = new byte[256]; for (uint w = 0; w < 256; ++w) { _pbState[w] = (byte)w; } unchecked { byte j = 0, t; uint inxKey = 0; for (uint w = 0; w < 256; ++w) // Key setup { j += (byte)(_pbState[w] + pbKey[inxKey]); t = _pbState[0]; // Swap entries _pbState[0] = _pbState[j]; _pbState[j] = t; ++inxKey; if (inxKey >= uKeyLen) { inxKey = 0; } } } GetRandomBytes(512); // Increases security, see cryptanalysis break; case CrsAlgorithm.Salsa20: { var sha256 = new SHA256Managed(); var pbKey32 = sha256.ComputeHash(pbKey); var pbIV = new byte[] { 0xE8, 0x30, 0x09, 0x4B, 0x97, 0x20, 0x5D, 0x2A }; // Unique constant _salsa20 = new Salsa20Cipher(pbKey32, pbIV); } break; default: throw new ArgumentException(); } }