public TeraEncryptionSession(Direction direction,
                                     byte[] clientKey1, byte[] clientKey2, byte[] serverKey1, byte[] serverKey2)
        {
            direction.CheckValidity(nameof(direction));
            CheckKey(clientKey1, nameof(clientKey1));
            CheckKey(clientKey2, nameof(clientKey2));
            CheckKey(serverKey1, nameof(serverKey1));
            CheckKey(serverKey2, nameof(serverKey2));

            Direction = direction;

            _clientKey1 = clientKey1.ToArray();
            _clientKey2 = clientKey2.ToArray();
            _serverKey1 = serverKey1.ToArray();
            _serverKey2 = serverKey2.ToArray();

            _decryptKey = XorKey(ShiftKey(clientKey2, 29, false),
                                 XorKey(ShiftKey(serverKey1, 67, true), clientKey1));
            _decryptor = new TeraEncryption(_decryptKey);

            var tmp = ShiftKey(serverKey2, 41, true);

            _decryptor.Apply(tmp, 0, tmp.Length);

            _encryptKey = tmp;
            _encryptor  = new TeraEncryption(_encryptKey);
        }
        public TeraEncryptionSession(Direction direction, byte[] clientKey1,
                                     byte[] clientKey2, byte[] serverKey1, byte[] serverKey2)
        {
            Direction = direction;

            _clientKey1 = clientKey1.ToArray();
            _clientKey2 = clientKey2.ToArray();
            _serverKey1 = serverKey1.ToArray();
            _serverKey2 = serverKey2.ToArray();

            var tmpKey1 = ShiftKey(serverKey1, 67, true);
            var tmpKey2 = XorKey(tmpKey1, clientKey1);

            tmpKey1 = ShiftKey(clientKey2, 29, false);

            _decryptKey = XorKey(tmpKey1, tmpKey2);
            _decryptor  = new TeraEncryption(_decryptKey);

            tmpKey1 = ShiftKey(serverKey2, 41, true);

            _decryptor.Apply(tmpKey1, 0, tmpKey1.Length);

            _encryptKey = tmpKey1;
            _encryptor  = new TeraEncryption(_encryptKey);
        }