/// <exception cref="ArgumentException">Wrong length of IV.</exception>
        public ICryptoTransform Create(CryptoDirection direction, Mode mode, byte[] iv)
        {
            if (iv.Length != BlockSize)
            {
                throw new ArgumentException("Wrong length of IV.");
            }

            InitRoundKey(direction);

            switch (mode)
            {
            default:
            case Mode.ECB:
                if (direction == CryptoDirection.Encrypt)
                {
                    return(new FROGEncryptTransform(_encryptRoundKeys));
                }
                else
                {
                    return(new FROGDecryptTransform(_decryptRoundKeys));
                }

            case Mode.CBC:
                return(CBC.Get(CreateNice(direction), iv, direction));

            case Mode.CFB:
                return(CFB.Get(CreateNice(CryptoDirection.Encrypt), iv, direction));

            case Mode.OFB:
                return(OFB.Get(CreateNice(CryptoDirection.Encrypt), iv, direction));
            }
        }
        private static byte[] TransformEmptyText(byte[][][] preliminaryKey, byte[] iv)
        {
            int blocksCount = 2304 / BlockSize;

            byte[]           buf       = new byte[BlockSize];
            byte[]           result    = new byte[2304];
            ICryptoTransform transform = CBC.Get(new FROGEncryptTransform(preliminaryKey), iv, CryptoDirection.Encrypt);

            for (int i = 0; i < blocksCount; i++)
            {
                Array.Fill <byte>(buf, 0);
                transform.TransformBlock(buf, 0, BlockSize, result, i * BlockSize);
            }
            return(result);
        }
        /// <exception cref="ArgumentException">Wrong key length or IV length</exception>
        public static ICryptoTransform Get(byte[] key, Size stateSize, byte[] IV, Mode mode, CryptoDirection direction)
        {
            switch (mode)
            {
            default:
            case Mode.ECB:
                return(Get(key, stateSize, direction));

            case Mode.CBC:
                return(CBC.Get(GetNice(key, stateSize, direction), IV, direction));

            case Mode.CFB:
                return(CFB.Get(GetNice(key, stateSize, CryptoDirection.Encrypt), IV, direction));

            case Mode.OFB:
                return(OFB.Get(GetNice(key, stateSize, CryptoDirection.Encrypt), IV, direction));
            }
        }