/// <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();
            }
        }
Beispiel #2
0
        /// <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();
            }
        }