public void Encrypt(ref byte[] src, ref byte[] dst, int size, ref int index_in, ref int index_out) { while (_stream_pos + size > Crypt_Constants.CRYPT_GAME_TABLE_TRIGGER) { int len_remaining = Crypt_Constants.CRYPT_GAME_TABLE_TRIGGER - _stream_pos; Encrypt(ref src, ref dst, len_remaining, ref index_in, ref index_out); _table_index = (_table_index + Crypt_Constants.CRYPT_GAME_TABLE_STEP) % Crypt_Constants.CRYPT_GAME_TABLE_MODULO; Array.Copy (Crypt_Constants.g_seed_table[1][_table_index][0], _seed, Crypt_Constants.CRYPT_GAME_SEED_LENGTH); _stream_pos = 0; _block_pos = 0; index_in += len_remaining; index_out += len_remaining; size -= len_remaining; } uint value_0 = 0, value_1 = 0; for (int i = 0; i < size; i++) { if (_block_pos == 0) { value_0 = 0; value_1 = 0; fixed(byte *ptr = _seed) { byte *p = ptr; Crypt_Constants.N2L(ref p, ref value_0); Crypt_Constants.N2L(ref p, ref value_1); RawEncrypt(ref value_0, ref value_1, _table_index); fixed(byte *ptr2 = _seed) { p = ptr2; Crypt_Constants.L2N(ref value_0, ref p); Crypt_Constants.L2N(ref value_1, ref p); } } } dst[i] = (byte)(src[i] ^ _seed[_block_pos]); _seed[_block_pos] = dst[i]; _block_pos = (_block_pos + 1) % 8; } _stream_pos += size; }
private static void RawEncrypt(ref uint value_0, ref uint value_1, int table) { uint left = value_0; uint right = value_1; left ^= Crypt_Constants.p_table[table][0]; for (int i = 1; i < 16; i += 2) { Crypt_Constants.Round(ref right, left, Crypt_Constants.s_table[table], Crypt_Constants.p_table[table][i]); Crypt_Constants.Round(ref left, right, Crypt_Constants.s_table[table], Crypt_Constants.p_table[table][i + 1]); } right ^= Crypt_Constants.p_table[table][17]; value_1 = left; value_0 = right; }