TripleDesCipher
Implements 3DES cipher algorithm.
            
                using System;
namespace Renci.SshNet.Security.Cryptography.Ciphers
{
    public sealed class TripleDesCipher : DesCipher
    {
        private int[] _encryptionKey1;
        private int[] _encryptionKey2;
        private int[] _encryptionKey3;
        private int[] _decryptionKey1;
        private int[] _decryptionKey2;
        private int[] _decryptionKey3;
        public TripleDesCipher(byte[] key, CipherMode mode, CipherPadding padding)
            : base(key, mode, padding)
        {
        }
        public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
        {
            if (inputOffset + base.BlockSize > inputBuffer.Length)
                throw new ArgumentException("input buffer too short");
            if (outputOffset + base.BlockSize > outputBuffer.Length)
                throw new ArgumentException("output buffer too short");
            if (_encryptionKey1 == null || _encryptionKey2 == null || _encryptionKey3 == null) {
                byte[] array = new byte[8];
                byte[] array2 = new byte[8];
                Buffer.BlockCopy(base.Key, 0, array, 0, 8);
                Buffer.BlockCopy(base.Key, 8, array2, 0, 8);
                _encryptionKey1 = GenerateWorkingKey(true, array);
                _encryptionKey2 = GenerateWorkingKey(false, array2);
                if (base.Key.Length == 24) {
                    byte[] array3 = new byte[8];
                    Buffer.BlockCopy(base.Key, 16, array3, 0, 8);
                    _encryptionKey3 = GenerateWorkingKey(true, array3);
                } else
                    _encryptionKey3 = _encryptionKey1;
            }
            byte[] array4 = new byte[base.BlockSize];
            DesCipher.DesFunc(_encryptionKey1, inputBuffer, inputOffset, array4, 0);
            DesCipher.DesFunc(_encryptionKey2, array4, 0, array4, 0);
            DesCipher.DesFunc(_encryptionKey3, array4, 0, outputBuffer, outputOffset);
            return base.BlockSize;
        }
        public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
        {
            if (inputOffset + base.BlockSize > inputBuffer.Length)
                throw new ArgumentException("input buffer too short");
            if (outputOffset + base.BlockSize > outputBuffer.Length)
                throw new ArgumentException("output buffer too short");
            if (_decryptionKey1 == null || _decryptionKey2 == null || _decryptionKey3 == null) {
                byte[] array = new byte[8];
                byte[] array2 = new byte[8];
                Buffer.BlockCopy(base.Key, 0, array, 0, 8);
                Buffer.BlockCopy(base.Key, 8, array2, 0, 8);
                _decryptionKey1 = GenerateWorkingKey(false, array);
                _decryptionKey2 = GenerateWorkingKey(true, array2);
                if (base.Key.Length == 24) {
                    byte[] array3 = new byte[8];
                    Buffer.BlockCopy(base.Key, 16, array3, 0, 8);
                    _decryptionKey3 = GenerateWorkingKey(false, array3);
                } else
                    _decryptionKey3 = _decryptionKey1;
            }
            byte[] array4 = new byte[base.BlockSize];
            DesCipher.DesFunc(_decryptionKey3, inputBuffer, inputOffset, array4, 0);
            DesCipher.DesFunc(_decryptionKey2, array4, 0, array4, 0);
            DesCipher.DesFunc(_decryptionKey1, array4, 0, outputBuffer, outputOffset);
            return base.BlockSize;
        }
        protected override void ValidateKey()
        {
            int num = base.Key.Length * 8;
            if ((num != 128 && num != 192) || 1 == 0)
                throw new ArgumentException($"""{num}""");
        }
    }
}