/// <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();
			}
		}
Example #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();
            }
        }
        /// <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();
            
            }
        }
Example #4
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)
        {
            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);
        }
Example #7
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)
        {
            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();
            }
        }
Example #10
0
        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);
        }
Example #11
0
        /// <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");
            }
        }
Example #12
0
        /// <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();
            }
        }
Example #13
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();
            }
        }