/// <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) { 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(); } }