diff --git a/Common/Configuration/ConfigContainer.cs b/Common/Configuration/ConfigContainer.cs index 35bfb8e7..4e917a0c 100644 --- a/Common/Configuration/ConfigContainer.cs +++ b/Common/Configuration/ConfigContainer.cs @@ -44,6 +44,7 @@ public class GameServerConfig public string GameServerId { get; set; } = "dan_heng"; public string GameServerName { get; set; } = "DanhengServer"; public string GameServerDescription { get; set; } = "A re-implementation of StarRail server"; + public bool UsePacketEncryption { get; set; } = true; public string GetDisplayAddress() { diff --git a/Common/Internationalization/Message/LanguageCHS.cs b/Common/Internationalization/Message/LanguageCHS.cs index 6466c2a4..fa5c734f 100644 --- a/Common/Internationalization/Message/LanguageCHS.cs +++ b/Common/Internationalization/Message/LanguageCHS.cs @@ -142,6 +142,7 @@ public class ServerInfoTextCHS public string LoadingItem => "正在加载 {0}…"; public string RegisterItem => "注册了 {0} 个 {1}。"; public string FailedToLoadItem => "加载 {0} 失败。"; + public string NewClientSecretKey => "客户端密钥不存在,正在生成新的客户端密钥。"; public string FailedToInitializeItem => "初始化 {0} 失败。"; public string FailedToReadItem => "读取 {0} 失败,文件{1}"; public string GeneratedItem => "已生成 {0}。"; diff --git a/Common/Internationalization/Message/LanguageCHT.cs b/Common/Internationalization/Message/LanguageCHT.cs index cb44eae7..5a15791d 100644 --- a/Common/Internationalization/Message/LanguageCHT.cs +++ b/Common/Internationalization/Message/LanguageCHT.cs @@ -140,6 +140,7 @@ public class ServerInfoTextCHT public string LoadingItem => "正在加載 {0}…"; public string RegisterItem => "註冊了 {0} 個 {1}。"; public string FailedToLoadItem => "加載 {0} 失敗。"; + public string NewClientSecretKey => "客戶端密鑰不存在,正在產生新的客戶端密鑰。"; public string FailedToInitializeItem => "初始化 {0} 失敗。"; public string FailedToReadItem => "讀取 {0} 失敗,文件{1}"; public string GeneratedItem => "已生成 {0}。"; diff --git a/Common/Internationalization/Message/LanguageEN.cs b/Common/Internationalization/Message/LanguageEN.cs index 1f69e133..0dc88463 100644 --- a/Common/Internationalization/Message/LanguageEN.cs +++ b/Common/Internationalization/Message/LanguageEN.cs @@ -140,6 +140,7 @@ public class ServerInfoTextEN public string LoadingItem => "Loading {0}..."; public string RegisterItem => "Registered {0} {1}(s)."; public string FailedToLoadItem => "Failed to load {0}."; + public string NewClientSecretKey => "Client Secret Key does not exist and a new Client Secret Key is being generated."; public string FailedToInitializeItem => "Failed to initialize {0}."; public string FailedToReadItem => "Failed to read {0}, file {1}"; public string GeneratedItem => "Generated {0}."; diff --git a/Common/Util/Crypto.cs b/Common/Util/Crypto.cs index 625e0ce2..f23f2c15 100644 --- a/Common/Util/Crypto.cs +++ b/Common/Util/Crypto.cs @@ -1,5 +1,7 @@ using System.Security.Cryptography; using System.Text; +using EggLink.DanhengServer.Internationalization; +using EggLink.DanhengServer.Util.Security; namespace EggLink.DanhengServer.Util; @@ -8,6 +10,8 @@ public class Crypto private static readonly Random SecureRandom = new(); public static Logger Logger = new("Crypto"); + public static Ec2b? ClientSecretKey { get; set; } + public static void Xor(byte[] packet, byte[] key) { try @@ -20,6 +24,56 @@ public class Crypto } } + public static byte[] GenerateXorKey(ulong seed) + { + byte[] key = new byte[4096]; + MT19937 random = new MT19937(seed); + + for (int i = 0; i < key.Length / 8; i++) + { + ulong value = random.NextUInt64(); + + key[i * 8 + 0] = (byte)((value >> 56) & 0xFF); + key[i * 8 + 1] = (byte)((value >> 48) & 0xFF); + key[i * 8 + 2] = (byte)((value >> 40) & 0xFF); + key[i * 8 + 3] = (byte)((value >> 32) & 0xFF); + key[i * 8 + 4] = (byte)((value >> 24) & 0xFF); + key[i * 8 + 5] = (byte)((value >> 16) & 0xFF); + key[i * 8 + 6] = (byte)((value >> 8) & 0xFF); + key[i * 8 + 7] = (byte)(value & 0xFF); + } + + return key; + } + + public static Ec2b? InitEc2b() + { + string filePath = ConfigManager.Config.Path.ConfigPath + "/ClientSecretKey.ec2b"; + try + { + byte[] ec2bData; + if (!File.Exists(filePath)) + { + Ec2b newEc2b = Ec2b.GenerateEc2b(); + ec2bData = newEc2b.GetBytes(); + File.WriteAllBytes(filePath, ec2bData); + Logger.Info(I18NManager.Translate("Server.ServerInfo.NewClientSecretKey")); + return newEc2b; + } + else + { + ec2bData = File.ReadAllBytes(filePath); + Ec2b ec2b = Ec2b.Read(ec2bData); + return ec2b; + } + } + catch (Exception ex) + { + Logger.Error($"An error occurred while loading the Encryption Seed:{ex}"); + return null; + } + } + // Simple way to create a unique session key public static string CreateSessionKey(string accountUid) { diff --git a/Common/Util/Security/AES128.cs b/Common/Util/Security/AES128.cs new file mode 100644 index 00000000..31b607bc --- /dev/null +++ b/Common/Util/Security/AES128.cs @@ -0,0 +1,226 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Util.Security +{ + public class AES128 + { + private static void Xor(byte[] a, byte[] b, int n) + { + for (int i = 0; i < n; i++) + { + a[i] ^= b[i]; + } + } + + private static void XorRoundKey(byte[] state, byte[] keys, int round) + { + Xor(state, keys.Skip(round * 16).Take(16).ToArray(), 16); + } + + private static void SubBytes(byte[] a, int n) + { + for (int i = 0; i < n; i++) + { + a[i] = Magic.LookupSbox[a[i]]; + } + } + private static void SubBytesInv(byte[] a, int n) + { + for (int i = 0; i < n; i++) + { + a[i] = Magic.LookupSboxInv[a[i]]; + } + } + + private static void KeyScheduleCore(byte[] a, int i) + { + byte temp = a[0]; + a[0] = a[1]; + a[1] = a[2]; + a[2] = a[3]; + a[3] = temp; + + SubBytes(a, 4); + + a[0] ^= Magic.LookupRcon[i]; + } + + public static void Aes128LoadSchedule(byte[] key, out byte[] schedule) + { + schedule = new byte[16 * 11]; + int bytes = 16; + int i = 1; + byte[] t = new byte[4]; + + Array.Copy(key, schedule, 16); + + while (bytes < 176) + { + Array.Copy(schedule, bytes - 4, t, 0, 4); + + KeyScheduleCore(t, i); + i++; + + for (int k = 0; k < 4; k++) + { + t[k] ^= schedule[bytes - 16 + k]; + } + + Array.Copy(t, 0, schedule, bytes, 4); + bytes += 4; + + for (int j = 0; j < 3; j++) + { + Array.Copy(schedule, bytes - 4, t, 0, 4); + + for (int k = 0; k < 4; k++) + { + t[k] ^= schedule[bytes - 16 + k]; + } + + Array.Copy(t, 0, schedule, bytes, 4); + bytes += 4; + } + } + } + + private static void ShiftRows(byte[] state) + { + byte[] temp = new byte[16]; + Array.Copy(state, temp, 16); + + for (int i = 0; i < 16; i++) + { + state[i] = temp[Magic.ShiftRowsTable[i]]; + } + } + private static void ShiftRowsInv(byte[] state) + { + byte[] temp = new byte[16]; + Array.Copy(state, temp, 16); + + for (int i = 0; i < 16; i++) + { + state[i] = temp[Magic.ShiftRowsTableInv[i]]; + } + } + + private static void MixCol(byte[] state, int offset) + { + byte a0 = state[offset]; + byte a1 = state[offset + 1]; + byte a2 = state[offset + 2]; + byte a3 = state[offset + 3]; + + state[offset] = (byte)(Magic.LookupG2[a0] ^ Magic.LookupG3[a1] ^ a2 ^ a3); + state[offset + 1] = (byte)(Magic.LookupG2[a1] ^ Magic.LookupG3[a2] ^ a3 ^ a0); + state[offset + 2] = (byte)(Magic.LookupG2[a2] ^ Magic.LookupG3[a3] ^ a0 ^ a1); + state[offset + 3] = (byte)(Magic.LookupG2[a3] ^ Magic.LookupG3[a0] ^ a1 ^ a2); + } + + private static void MixCols(byte[] state) + { + MixCol(state, 0); + MixCol(state, 4); + MixCol(state, 8); + MixCol(state, 12); + } + + private static void MixColInv(byte[] state, int offset) + { + byte a0 = state[offset]; + byte a1 = state[offset + 1]; + byte a2 = state[offset + 2]; + byte a3 = state[offset + 3]; + + state[offset] = (byte)(Magic.LookupG14[a0] ^ Magic.LookupG9[a3] ^ Magic.LookupG13[a2] ^ Magic.LookupG11[a1]); + state[offset + 1] = (byte)(Magic.LookupG14[a1] ^ Magic.LookupG9[a0] ^ Magic.LookupG13[a3] ^ Magic.LookupG11[a2]); + state[offset + 2] = (byte)(Magic.LookupG14[a2] ^ Magic.LookupG9[a1] ^ Magic.LookupG13[a0] ^ Magic.LookupG11[a3]); + state[offset + 3] = (byte)(Magic.LookupG14[a3] ^ Magic.LookupG9[a2] ^ Magic.LookupG13[a1] ^ Magic.LookupG11[a0]); + } + + private static void MixColsInv(byte[] state) + { + MixColInv(state, 0); + MixColInv(state, 4); + MixColInv(state, 8); + MixColInv(state, 12); + } + + public static void Aes128Enc(byte[] plaintext, byte[] schedule, byte[] ciphertext) + { + Array.Copy(plaintext, ciphertext, 16); + XorRoundKey(ciphertext, schedule, 0); + + for (int i = 0; i < 9; i++) + { + SubBytes(ciphertext, 16); + ShiftRows(ciphertext); + MixCols(ciphertext); + XorRoundKey(ciphertext, schedule, i + 1); + } + + SubBytes(ciphertext, 16); + ShiftRows(ciphertext); + XorRoundKey(ciphertext, schedule, 10); + } + + public static void RevAes128Enc(byte[] plaintext, byte[] schedule, byte[] ciphertext) + { + Array.Copy(plaintext, ciphertext, 16); + XorRoundKey(ciphertext, schedule, 0); + + for (int i = 0; i < 9; i++) + { + SubBytesInv(ciphertext, 16); + ShiftRowsInv(ciphertext); + MixColsInv(ciphertext); + XorRoundKey(ciphertext, schedule, i + 1); + } + + SubBytesInv(ciphertext, 16); + ShiftRowsInv(ciphertext); + XorRoundKey(ciphertext, schedule, 10); + } + + public static void Aes128Dec(byte[] ciphertext, byte[] schedule, byte[] plaintext) + { + Array.Copy(ciphertext, plaintext, 16); + XorRoundKey(plaintext, schedule, 10); + ShiftRowsInv(plaintext); + SubBytesInv(plaintext, 16); + + for (int i = 0; i < 9; i++) + { + XorRoundKey(plaintext, schedule, 9 - i); + MixColsInv(plaintext); + ShiftRowsInv(plaintext); + SubBytesInv(plaintext, 16); + } + + XorRoundKey(plaintext, schedule, 0); + } + + public static void RevAes128Dec(byte[] ciphertext, byte[] schedule, byte[] plaintext) + { + Array.Copy(ciphertext, plaintext, 16); + XorRoundKey(plaintext, schedule, 10); + ShiftRows(plaintext); + SubBytes(plaintext, 16); + + for (int i = 0; i < 9; i++) + { + XorRoundKey(plaintext, schedule, 9 - i); + MixCols(plaintext); + ShiftRows(plaintext); + SubBytes(plaintext, 16); + } + + XorRoundKey(plaintext, schedule, 0); + } + } +} diff --git a/Common/Util/Security/Ec2b.cs b/Common/Util/Security/Ec2b.cs new file mode 100644 index 00000000..634fa1f8 --- /dev/null +++ b/Common/Util/Security/Ec2b.cs @@ -0,0 +1,186 @@ +using System; +using System.Buffers.Binary; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace EggLink.DanhengServer.Util.Security +{ + public class Ec2b + { + private const int HEAD_MAGIC = 1647469381; // "Ec2b" + private const int KEY_SIZE = 16; + private const int DATA_SIZE = 2048; + + private byte[] Key; + private byte[] Data; + + private ulong Seed; + private byte[] xorKey; + +#pragma warning disable CS8618 // CS8618 - Non-nullable variable must contain a non-null value when exiting constructor. + private Ec2b(byte[] key, byte[] data) +#pragma warning restore CS8618 // CS8618 - Non-nullable variable must contain a non-null value when exiting constructor. + { + Key = key; + Data = data; + byte[] scrambledKey = new byte[KEY_SIZE]; + Array.Copy(Key, scrambledKey, KEY_SIZE); + KeyScramble(scrambledKey); + GenerateDecryptionVector(scrambledKey, Data); + } + + public static Ec2b Read(byte[] input) + { + if (input == null || input.Length < 2076) + { + throw new Exception("Input data is too short."); + } + + int offset = 0; + + int magic = BinaryPrimitives.ReadInt32LittleEndian(input.AsSpan(offset, 4)); + if (magic != HEAD_MAGIC) + { + throw new Exception($"Magic mismatch, expected: {HEAD_MAGIC}, got: {magic}"); + } + offset += 4; + + int keySize = BinaryPrimitives.ReadInt32LittleEndian(input.AsSpan(offset, 4)); + offset += 4; + if (keySize != KEY_SIZE) + { + throw new Exception($"Invalid key size, expected: {KEY_SIZE}, got: {keySize}"); + } + + if (input.Length < offset + KEY_SIZE) + { + throw new Exception("Input data is too short for key."); + } + byte[] key = new byte[KEY_SIZE]; + Array.Copy(input, offset, key, 0, KEY_SIZE); + offset += KEY_SIZE; + + if (input.Length < offset + 4) + { + throw new Exception("Input data is too short for data size."); + } + int dataSize = BinaryPrimitives.ReadInt32LittleEndian(input.AsSpan(offset, 4)); + offset += 4; + if (dataSize != DATA_SIZE) + { + throw new Exception($"Invalid data size, expected: {DATA_SIZE}, got: {dataSize}"); + } + + if (input.Length < offset + DATA_SIZE) + { + throw new Exception("Input data is too short for data."); + } + byte[] data = new byte[DATA_SIZE]; + Array.Copy(input, offset, data, 0, DATA_SIZE); + + return new Ec2b(key, data); + } + + public static Ec2b GenerateEc2b() + { + byte[] key = new byte[KEY_SIZE]; + byte[] data = new byte[DATA_SIZE]; + + MT19937 random = new MT19937((ulong)DateTimeOffset.UtcNow.ToUnixTimeSeconds()); + + for (int i = 0; i < KEY_SIZE; i++) + key[i] = (byte)(random.NextUInt64() % 256); + + for (int i = 0; i < DATA_SIZE; i++) + data[i] = (byte)(random.NextUInt64() % 256); + + return new Ec2b(key, data); + } + + public byte[] GetBytes() + { + byte[] output = new byte[4 + 4 + KEY_SIZE + 4 + DATA_SIZE]; + int offset = 0; + + BinaryPrimitives.WriteInt32LittleEndian(output.AsSpan(offset, 4), HEAD_MAGIC); + offset += 4; + + BinaryPrimitives.WriteInt32LittleEndian(output.AsSpan(offset, 4), KEY_SIZE); + offset += 4; + + Array.Copy(Key, 0, output, offset, KEY_SIZE); + offset += KEY_SIZE; + + BinaryPrimitives.WriteInt32LittleEndian(output.AsSpan(offset, 4), DATA_SIZE); + offset += 4; + + Array.Copy(Data, 0, output, offset, DATA_SIZE); + + return output; + } + + public ulong GetSeed() + { + return Seed; + } + + public byte[] GetXorKey() + { + return xorKey; + } + + private void GenerateDecryptionVector(byte[] key, byte[] crypt) + { + List output = new List(4096); + + ulong val = 18446744073709551615; + for (int i = 0; i < crypt.Length; i += 8) + { + ulong chunk = BitConverter.ToUInt64(crypt, i); + val ^= chunk; + } + + ulong key_qword_0 = BitConverter.ToUInt64(key, 0); + ulong key_qword_1 = BitConverter.ToUInt64(key, 8); + + Seed = key_qword_1 ^ 0b1100111010101100001110110101101010000110011110000011011110101100 ^ val ^ key_qword_0; + + MT19937 mt = new MT19937(Seed); + for (int i = 0; i < 512; i++) + { + ulong next = mt.NextUInt64(); + byte[] bytes = BitConverter.GetBytes(next); + output.AddRange(bytes); + } + + xorKey = output.ToArray(); + } + + private static void KeyScramble(byte[] key) + { + byte[] roundKeys = new byte[176]; + for (int round = 0; round < 11; round++) + { + for (int i = 0; i < 16; i++) + { + for (int j = 0; j < 16; j++) + { + int idx = (round << 8) + (i * 16) + j; + roundKeys[round * 16 + i] ^= (byte)(Magic.aesXorTable[1, idx] ^ Magic.aesXorTable[0, idx]); + } + } + } + + byte[] chip = new byte[16]; + AES128.RevAes128Enc(key, roundKeys, chip); + + for (int i = 0; i < KEY_SIZE; i++) + { + chip[i] ^= Magic.keyXorTable[i]; + } + + Array.Copy(chip, key, KEY_SIZE); + } + } +} diff --git a/Common/Util/Security/MT19937.cs b/Common/Util/Security/MT19937.cs new file mode 100644 index 00000000..8291f7eb --- /dev/null +++ b/Common/Util/Security/MT19937.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Util.Security +{ + public class MT19937 + { + private const int N = 312; + private const int M = 156; + private const ulong MATRIX_A = 13043109905998158313UL; + private const ulong UPPER_MASK = 18446744071562067968UL; + private const ulong LOWER_MASK = 2147483647UL; + + private ulong[] mt = new ulong[N]; + private int mti = N + 1; + + public MT19937() + { + Seed(5489UL); // MT19937 default seed + } + + public MT19937(ulong seed) + { + Seed(seed); + } + + public void Seed(ulong seed) + { + mt[0] = seed; + for (mti = 1; mti < N; mti++) + { + mt[mti] = 6364136223846793005UL * (mt[mti - 1] ^ mt[mti - 1] >> 62) + (ulong)mti; + } + } + + public ulong NextUInt64() + { + ulong x; + ulong[] mag01 = { 0UL, MATRIX_A }; + + if (mti >= N) + { + int i; + + if (mti == N + 1) + { + Seed(5489UL); + } + + for (i = 0; i < N - M; i++) + { + x = mt[i] & UPPER_MASK | mt[i + 1] & LOWER_MASK; + mt[i] = mt[i + M] ^ x >> 1 ^ mag01[x & 1UL]; + } + for (; i < N - 1; i++) + { + x = mt[i] & UPPER_MASK | mt[i + 1] & LOWER_MASK; + mt[i] = mt[i + (M - N)] ^ x >> 1 ^ mag01[x & 1UL]; + } + x = mt[N - 1] & UPPER_MASK | mt[0] & LOWER_MASK; + mt[N - 1] = mt[M - 1] ^ x >> 1 ^ mag01[x & 1UL]; + + mti = 0; + } + + x = mt[mti++]; + x ^= x >> 29 & 0x5555555555555555UL; + x ^= x << 17 & 0x71D67FFFEDA60000UL; + x ^= x << 37 & 0xFFF7EEE000000000UL; + x ^= x >> 43; + + return x; + } + + public long NextInt63() + { + return (long)(NextUInt64() & 0x7FFFFFFFFFFFFFFFUL); + } + } +} diff --git a/Common/Util/Security/Magic.cs b/Common/Util/Security/Magic.cs new file mode 100644 index 00000000..85685df3 --- /dev/null +++ b/Common/Util/Security/Magic.cs @@ -0,0 +1,541 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EggLink.DanhengServer.Util.Security +{ + public class Magic + { + public static readonly byte[] ShiftRowsTable = new byte[16] + { + 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11 + }; + public static readonly byte[] ShiftRowsTableInv = new byte[16] + { + 0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3 + }; + public static readonly byte[] LookupRcon = new byte[16] + { + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a + }; + public static readonly byte[] LookupSbox = new byte[256] + { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 + }; + public static readonly byte[] LookupSboxInv = new byte[256] + { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d + }; + public static readonly byte[] LookupG2 = new byte[256] + { + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, + 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, + 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, + 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, + 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, + 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, + 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, + 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, + 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, + 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, + 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, + 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, + 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, + 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, + 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, + 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 + }; + public static readonly byte[] LookupG3 = new byte[256] + { + 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, + 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, + 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, + 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, + 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, + 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, + 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, + 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, + 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, + 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, + 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, + 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, + 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, + 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, + 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, + 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a + }; + public static readonly byte[] LookupG9 = new byte[256] + { + 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, + 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, + 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, + 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc, + 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, + 0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91, + 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a, + 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, + 0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b, + 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b, + 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, + 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30, + 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed, + 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, + 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, + 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46 + }; + public static readonly byte[] LookupG11 = new byte[256] + { + 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69, + 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, + 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12, + 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2, + 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, + 0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f, + 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4, + 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, + 0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e, + 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e, + 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, + 0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55, + 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, + 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, + 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, + 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3 + }; + public static readonly byte[] LookupG13 = new byte[256] + { + 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b, + 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, + 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0, + 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20, + 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, + 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6, + 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d, + 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, + 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91, + 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41, + 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, + 0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa, + 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc, + 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, + 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, + 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97 + }; + public static readonly byte[] LookupG14 = new byte[256] + { + 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, + 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, + 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81, + 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61, + 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, + 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17, + 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c, + 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, + 0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b, + 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb, + 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, + 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20, + 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, + 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, + 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, + 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d + }; + + public static readonly byte[] keyXorTable = new byte[16] + { + 162, 37, 37, 153, 183, 98, 244, 57, 40, 225, 183, 115, 145, 5, 37, 135 + }; + + public static readonly byte[,] aesXorTable = new byte[2, 2816] + { + { + 0xDE, 0xAD, 0xCA, 0xFE, 0xFA, 0xCE, 0xB0, 0x0C, 0xDE, 0xAD, 0xCA, 0xFE, 0xFA, 0xCE, 0xB0, 0x0C, + 0x3A, 0xE6, 0xDE, 0x9C, 0x81, 0xBA, 0x7C, 0xC6, 0x12, 0x1B, 0xAF, 0xD2, 0x8A, 0xBA, 0xF5, 0xE6, + 0x41, 0xDF, 0x71, 0xBA, 0x37, 0x11, 0x50, 0xF3, 0xF3, 0x62, 0x6E, 0x04, 0xF1, 0x14, 0xFC, 0xBD, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x7B, 0x52, 0x7C, 0x19, 0x98, 0x35, 0x96, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, + 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, + 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, + 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, + }, + { + 0xC3, 0x20, 0x20, 0xB4, 0xAF, 0x0E, 0x82, 0x2E, 0xEF, 0x29, 0xFE, 0x75, 0x1D, 0xDB, 0x4B, 0x86, + 0x86, 0x23, 0x28, 0x72, 0xA3, 0xF4, 0x1B, 0x4F, 0x5F, 0x0E, 0x02, 0xB1, 0xAC, 0x0D, 0xE6, 0x4F, + 0x8B, 0x0B, 0x3F, 0xF3, 0x5F, 0xB5, 0x09, 0x7E, 0x3B, 0xE9, 0x93, 0x29, 0x55, 0xE1, 0xB4, 0x9B, + 0xCC, 0xCE, 0x37, 0xFC, 0xAB, 0x6B, 0xA4, 0x05, 0xE6, 0xC7, 0x45, 0x34, 0xC0, 0xFF, 0x7C, 0x24, + 0x89, 0x36, 0xBF, 0x17, 0xAB, 0x91, 0xCA, 0x49, 0xF2, 0x74, 0x80, 0xB6, 0x90, 0x60, 0xFF, 0xD2, + 0xA9, 0xE5, 0xC9, 0x64, 0xBC, 0x38, 0x40, 0x98, 0xB3, 0xBA, 0x8F, 0x8B, 0xBA, 0x9D, 0xF3, 0xCF, + 0x57, 0xBA, 0xAC, 0x18, 0xE7, 0xD3, 0x03, 0x01, 0x48, 0x29, 0x41, 0xF6, 0x2F, 0x89, 0xD4, 0x9F, + 0xD7, 0xD3, 0x05, 0x71, 0x63, 0x30, 0x4E, 0xBB, 0xF7, 0xB0, 0x99, 0xFF, 0x43, 0xDA, 0x87, 0xCA, + 0xA7, 0x48, 0x92, 0x9E, 0x76, 0xA6, 0xEE, 0x48, 0x1C, 0x96, 0x28, 0x8E, 0x54, 0x30, 0xD6, 0xA5, + 0xD3, 0x22, 0xA2, 0x30, 0xCB, 0x6A, 0x85, 0x26, 0x69, 0xE1, 0x7C, 0xEC, 0xDC, 0xD4, 0x89, 0x2A, + 0xB8, 0xAE, 0xDF, 0x12, 0x6E, 0x39, 0x8A, 0x9B, 0x48, 0x61, 0xF9, 0x4B, 0x34, 0xD0, 0xF1, 0x60, + 0x87, 0xBA, 0x88, 0x86, 0x68, 0x8C, 0xBE, 0xC1, 0x9C, 0xAE, 0x30, 0xBC, 0xE6, 0x62, 0xFF, 0xEB, + 0xBB, 0x88, 0x7C, 0xD2, 0xBB, 0x57, 0xB4, 0x02, 0x82, 0x06, 0x72, 0xD2, 0x94, 0x60, 0x86, 0x4A, + 0x29, 0xF0, 0xEA, 0xD3, 0x88, 0x92, 0xF1, 0x22, 0xD1, 0x5C, 0x88, 0x65, 0xE6, 0xFB, 0xEE, 0x28, + 0x79, 0x86, 0x68, 0x7D, 0xA6, 0x5A, 0xBF, 0xBD, 0x7D, 0x15, 0xEF, 0x05, 0xF6, 0xF9, 0xE0, 0x11, + 0xD6, 0x30, 0x94, 0xF2, 0x6C, 0x3D, 0x0A, 0xDB, 0xC5, 0x0E, 0xDC, 0xF2, 0xFD, 0x1F, 0x61, 0x91, + 0x5D, 0x80, 0x69, 0xA3, 0xDB, 0x35, 0x98, 0x4E, 0x4A, 0xC1, 0x49, 0x76, 0xAB, 0xC0, 0x67, 0x36, + 0x3F, 0xA4, 0xC6, 0xE8, 0xCA, 0x25, 0x44, 0x63, 0x23, 0xB5, 0xC8, 0xBB, 0x3A, 0xAC, 0xA1, 0x09, + 0xC3, 0x10, 0x57, 0xA5, 0x5B, 0x3B, 0x33, 0x21, 0xCD, 0x3C, 0x88, 0xAE, 0x1E, 0x8F, 0xC1, 0xD6, + 0xFB, 0x94, 0x61, 0x38, 0xAB, 0xF1, 0x9C, 0x06, 0xCB, 0x89, 0x58, 0x9A, 0xF4, 0xF4, 0x33, 0x80, + 0x66, 0x13, 0xC0, 0xFD, 0xE2, 0x16, 0xE0, 0x89, 0x65, 0xE2, 0xC1, 0xA6, 0xE3, 0x74, 0xD2, 0x5F, + 0xA0, 0x76, 0xAD, 0xF5, 0x6B, 0x4F, 0xE0, 0xF7, 0x52, 0xB0, 0xB1, 0x48, 0xDD, 0xEE, 0xB6, 0x01, + 0x9A, 0x90, 0x91, 0x18, 0xEC, 0xCB, 0xCB, 0xAD, 0x04, 0xB6, 0x73, 0xCF, 0x7F, 0xF3, 0xAC, 0xBE, + 0xEC, 0x91, 0x44, 0x56, 0x81, 0xB8, 0x74, 0xAE, 0x28, 0x5D, 0xC7, 0x5C, 0xAB, 0x8B, 0x56, 0x21, + 0x32, 0x91, 0xB9, 0x9E, 0x70, 0xF6, 0x9B, 0xAC, 0x50, 0x0B, 0x2E, 0x4B, 0x8B, 0xA2, 0xA5, 0x24, + 0x5B, 0x91, 0xDF, 0x24, 0xA7, 0xB0, 0x79, 0xA7, 0x16, 0x54, 0x44, 0x2E, 0xBC, 0x48, 0xCD, 0x87, + 0xBA, 0xAF, 0xD4, 0xB9, 0x1C, 0x0F, 0xAA, 0xFA, 0x3A, 0x3F, 0x3A, 0x3D, 0x68, 0x5A, 0xAE, 0xAC, + 0xBA, 0xBE, 0xA3, 0x92, 0x6E, 0x38, 0x8E, 0x33, 0x3E, 0x0A, 0xCC, 0xF6, 0xE3, 0x26, 0x57, 0xEC, + 0x8E, 0x63, 0x31, 0x27, 0xBA, 0x20, 0x4E, 0x7F, 0x34, 0xE5, 0x19, 0xFE, 0x7F, 0xA6, 0x97, 0x90, + 0xD6, 0x29, 0x1C, 0x3F, 0x8C, 0x3F, 0x81, 0x62, 0x3D, 0xF5, 0x00, 0xD4, 0xC5, 0xE2, 0xE1, 0x42, + 0x42, 0x8C, 0x65, 0x8F, 0x5A, 0x66, 0x59, 0xE1, 0xDD, 0xEC, 0xDC, 0x1B, 0x4E, 0x63, 0x82, 0xFF, + 0x02, 0x9D, 0x53, 0xDE, 0xBD, 0xB4, 0x80, 0xCF, 0x2B, 0xB7, 0xDE, 0x69, 0x5D, 0x1B, 0xCA, 0xFB, + 0xB3, 0xF9, 0xBE, 0xD0, 0xF5, 0x79, 0x86, 0x2F, 0x0E, 0xB6, 0xA9, 0x87, 0xF4, 0x68, 0xC1, 0xBF, + 0x4F, 0xB8, 0xA6, 0x2D, 0x03, 0xA9, 0x72, 0x04, 0xCA, 0x37, 0x6D, 0x1B, 0x90, 0xDD, 0xBC, 0x52, + 0xAE, 0xF3, 0xFF, 0x08, 0xDD, 0x4B, 0x46, 0xD0, 0xCD, 0xB1, 0x8A, 0x35, 0x9A, 0x02, 0x64, 0x64, + 0x2F, 0x57, 0xA5, 0x7B, 0x9A, 0x0D, 0x2B, 0x55, 0x11, 0x3C, 0xC0, 0x35, 0x74, 0x69, 0xD9, 0x7B, + 0x43, 0x1D, 0xAC, 0xB2, 0xC2, 0x8A, 0xBE, 0x22, 0x45, 0x46, 0x76, 0xA9, 0x8A, 0x49, 0xB2, 0x5F, + 0xC0, 0xB8, 0xBC, 0xCD, 0x27, 0xF8, 0x14, 0xB2, 0xA9, 0x6D, 0x5A, 0x1F, 0xA4, 0x43, 0x1E, 0x0F, + 0xDB, 0xA4, 0x9E, 0x2B, 0xCA, 0xFC, 0x98, 0x7F, 0xF1, 0x18, 0x87, 0x5B, 0x11, 0x2D, 0xC5, 0xE4, + 0x91, 0x20, 0xA9, 0x6A, 0x2D, 0xAC, 0xA8, 0xFA, 0x94, 0x57, 0x7F, 0x30, 0x73, 0x08, 0xE8, 0x49, + 0xF0, 0xC8, 0x63, 0xDA, 0x83, 0x87, 0x2A, 0xC3, 0x31, 0x1A, 0xFC, 0xB7, 0x57, 0xB2, 0x40, 0x46, + 0x09, 0x6D, 0x84, 0xB4, 0x66, 0xF1, 0x13, 0x16, 0x3A, 0x3A, 0xFB, 0xC6, 0x6E, 0xB0, 0x71, 0xB8, + 0x23, 0x74, 0x22, 0x89, 0xFC, 0xBE, 0x34, 0xB3, 0x17, 0xB6, 0xC9, 0x68, 0x53, 0x64, 0x47, 0xAF, + 0xCA, 0x1D, 0x5F, 0xB4, 0x74, 0xA3, 0x77, 0xB5, 0xFB, 0x77, 0xD9, 0x69, 0x2B, 0x3A, 0xAA, 0xAE, + 0xE4, 0x03, 0x81, 0x6B, 0x3A, 0x35, 0x9C, 0x45, 0x50, 0x9C, 0x76, 0xCE, 0xE3, 0x7F, 0x64, 0x4B, + 0x9F, 0x83, 0x7B, 0x72, 0xBC, 0x02, 0x1E, 0x94, 0x99, 0xC1, 0x1C, 0x45, 0x19, 0x1D, 0x56, 0x74, + 0x73, 0xE7, 0xFC, 0x58, 0x72, 0x2D, 0xE3, 0x50, 0xA4, 0x21, 0xBE, 0x81, 0xDF, 0x80, 0xDA, 0x40, + 0xDB, 0x79, 0x67, 0x0E, 0x94, 0xA3, 0x05, 0xDD, 0xF7, 0x14, 0x28, 0xD6, 0xC4, 0x2B, 0xF3, 0xCF, + 0x36, 0x08, 0x84, 0xF3, 0xC8, 0x8C, 0xAD, 0xCE, 0x7F, 0x7C, 0x0F, 0xC6, 0xFE, 0x05, 0x54, 0x4B, + 0x17, 0xA1, 0x83, 0x65, 0x97, 0x29, 0x01, 0x70, 0xC1, 0x16, 0xAE, 0x69, 0xA4, 0x90, 0xB9, 0xBE, + 0x17, 0x05, 0x50, 0xF1, 0x65, 0x07, 0x23, 0x76, 0x64, 0x84, 0x2D, 0x40, 0x34, 0xFD, 0xDF, 0x62, + 0x7E, 0x4C, 0x85, 0xD2, 0x6D, 0x17, 0xE1, 0x41, 0x12, 0xC6, 0x3E, 0xD6, 0x14, 0xB8, 0x5F, 0x8F, + 0x39, 0x65, 0xC2, 0x62, 0x21, 0x06, 0x5C, 0xC9, 0xB8, 0x99, 0xA5, 0x00, 0xE3, 0x9C, 0x73, 0xAB, + 0xB9, 0x76, 0x12, 0xD2, 0xFA, 0x7F, 0x7D, 0x64, 0x63, 0x9E, 0x26, 0xAA, 0x89, 0x85, 0x3A, 0xC9, + 0x94, 0x04, 0x97, 0xEC, 0xFD, 0xC5, 0xA3, 0xB1, 0x7D, 0xD6, 0x07, 0x9C, 0x47, 0x30, 0x9C, 0x64, + 0x97, 0x0E, 0xC6, 0xFC, 0x0B, 0xFF, 0xA7, 0xF9, 0x46, 0x5B, 0x2B, 0xDB, 0x9E, 0x1C, 0x85, 0x3A, + 0x75, 0xD6, 0xEB, 0x9B, 0x15, 0x36, 0xD7, 0x1A, 0x3D, 0xFC, 0x0B, 0x75, 0x08, 0x5E, 0x32, 0x23, + 0xE0, 0xA5, 0xAD, 0x0F, 0x45, 0xB3, 0x78, 0x20, 0x22, 0x24, 0x64, 0x0C, 0xCF, 0xD6, 0x3C, 0xA4, + 0x48, 0xC7, 0xB3, 0x6E, 0x02, 0xE2, 0x0A, 0xAB, 0x92, 0xFC, 0x40, 0x7D, 0xF5, 0x02, 0x61, 0x56, + 0xAB, 0xC5, 0x68, 0x38, 0xE0, 0x01, 0xF1, 0x94, 0x73, 0xC6, 0xFE, 0xC2, 0x34, 0x67, 0x8E, 0xB1, + 0x73, 0x72, 0xD4, 0x3B, 0xFD, 0x1F, 0xE2, 0xA8, 0xED, 0x20, 0x14, 0x0A, 0x60, 0x6D, 0xD1, 0x85, + 0x14, 0x05, 0x54, 0x96, 0xC6, 0x3D, 0xB5, 0x1B, 0x37, 0x56, 0x24, 0xF7, 0x7C, 0x0F, 0x55, 0xC6, + 0xAA, 0x7E, 0x33, 0x2D, 0xE1, 0x97, 0x74, 0xA8, 0xDC, 0xC5, 0xA1, 0xEC, 0x8C, 0xEF, 0x28, 0x3B, + 0x49, 0x8B, 0x00, 0xED, 0x8B, 0xD9, 0xE9, 0x65, 0xD5, 0x05, 0x7B, 0x6D, 0x20, 0xCA, 0x8F, 0x93, + 0xB4, 0xCA, 0x36, 0x34, 0x8E, 0x16, 0x46, 0xCE, 0x02, 0x23, 0x43, 0x22, 0xF6, 0xBD, 0x10, 0xCC, + 0xD0, 0xA3, 0xB0, 0x42, 0xA5, 0xAF, 0x59, 0x72, 0x97, 0x0B, 0xAE, 0x80, 0x8D, 0x19, 0xD0, 0x1D, + 0x7D, 0x30, 0x4E, 0x5B, 0x46, 0xC0, 0xC2, 0x5C, 0x40, 0xFC, 0xF3, 0xEF, 0x05, 0x84, 0xE8, 0x0C, + 0x80, 0xD7, 0x37, 0xA1, 0x6F, 0xC1, 0x8C, 0xE0, 0xBA, 0xA1, 0x88, 0x7B, 0xE7, 0x20, 0xBF, 0x18, + 0x02, 0x40, 0x9F, 0x6F, 0x23, 0x11, 0x78, 0x07, 0xD0, 0x92, 0x87, 0x2D, 0xB5, 0xE0, 0xE9, 0xE9, + 0xAA, 0x32, 0x88, 0x57, 0xF8, 0x9B, 0x01, 0x93, 0x2D, 0x07, 0x77, 0x68, 0x86, 0xAD, 0x06, 0xDE, + 0x57, 0xA9, 0xA4, 0x96, 0x33, 0x42, 0xF8, 0xFB, 0x23, 0x1F, 0x99, 0xB6, 0x62, 0x93, 0x6B, 0x12, + 0xBE, 0x72, 0x9F, 0x96, 0x1A, 0xDA, 0x05, 0x60, 0xF1, 0xD5, 0x40, 0x9F, 0x75, 0xF3, 0x1D, 0xBE, + 0xD7, 0x87, 0x5D, 0x3A, 0x55, 0xF0, 0x9B, 0xBF, 0xE8, 0xB9, 0x72, 0xC2, 0xDD, 0x4D, 0x27, 0xF6, + 0xA9, 0x37, 0x96, 0x7E, 0x6E, 0x6E, 0x64, 0x37, 0x4E, 0x2E, 0x3F, 0xFD, 0x3C, 0xF4, 0xA6, 0xF5, + 0x22, 0xA8, 0x43, 0xF4, 0x13, 0x21, 0xB5, 0x4E, 0xA8, 0x6D, 0x50, 0x0A, 0xB3, 0xFE, 0x9F, 0x5C, + 0xE7, 0x1A, 0xCF, 0x36, 0x42, 0x30, 0x1C, 0x88, 0x7F, 0x29, 0xE9, 0xCD, 0x96, 0xF2, 0x6A, 0x52, + 0xB2, 0x25, 0x87, 0x63, 0xDC, 0xFC, 0x72, 0xE4, 0xF8, 0x5E, 0xB1, 0x97, 0xB4, 0x1E, 0x08, 0x90, + 0x68, 0x10, 0x73, 0x7F, 0x94, 0x61, 0x48, 0x49, 0x36, 0x9B, 0x7D, 0xBD, 0xDF, 0xCD, 0xB1, 0xA3, + 0x7D, 0xFB, 0xDD, 0x97, 0x8A, 0x0D, 0xFC, 0x9A, 0xB8, 0xA9, 0x33, 0xB5, 0x4E, 0x50, 0x3D, 0x60, + 0x90, 0xEB, 0xAB, 0xB8, 0xCB, 0x6E, 0x32, 0xE4, 0x6B, 0xB0, 0x3F, 0x57, 0xB8, 0xA4, 0x6A, 0x7C, + 0x00, 0x66, 0x39, 0xB1, 0x22, 0xE2, 0x04, 0x26, 0xA1, 0x5A, 0x17, 0xAA, 0x80, 0xB6, 0xC0, 0xF6, + 0xCF, 0x7A, 0xF8, 0x60, 0xE9, 0x52, 0xB8, 0x0E, 0x08, 0xC0, 0xD5, 0x1F, 0xAB, 0x61, 0x62, 0x1A, + 0x83, 0xD1, 0x92, 0xE1, 0x4D, 0x6D, 0xDF, 0x27, 0x0E, 0xFF, 0xF9, 0xA3, 0x36, 0xFF, 0x73, 0xEF, + 0x1D, 0xAB, 0xAC, 0xBF, 0xA7, 0xB3, 0x29, 0xD2, 0xB2, 0x37, 0xAB, 0x08, 0x7D, 0xB6, 0x7E, 0x0D, + 0x25, 0xAA, 0x49, 0x29, 0x9F, 0x61, 0x52, 0x44, 0x19, 0x1C, 0x51, 0x95, 0x74, 0xB9, 0x3D, 0xDD, + 0x95, 0x2C, 0x4F, 0x30, 0x56, 0xC9, 0xEF, 0x3D, 0x87, 0x90, 0x1E, 0xF8, 0x69, 0xFF, 0x37, 0x06, + 0x27, 0xDB, 0x72, 0x82, 0x2C, 0xDE, 0xB8, 0x39, 0x0B, 0x78, 0xB1, 0x1F, 0x37, 0x54, 0xBF, 0x21, + 0x32, 0x87, 0xB4, 0xD9, 0x49, 0x2D, 0x29, 0x19, 0x43, 0x01, 0xD4, 0xC0, 0xA3, 0xFF, 0x09, 0x6F, + 0x69, 0xC8, 0x5D, 0x35, 0x1D, 0x10, 0x09, 0x91, 0xB6, 0x12, 0xEC, 0x04, 0xA6, 0x61, 0xEF, 0x73, + 0xC7, 0x4C, 0x04, 0x8E, 0x3E, 0xAE, 0xD7, 0xC2, 0x84, 0x48, 0xAB, 0x99, 0x96, 0x75, 0xD8, 0xAD, + 0xA7, 0x5B, 0xDE, 0x72, 0x44, 0x96, 0xC5, 0xB3, 0xEB, 0x8E, 0xED, 0xD6, 0x69, 0x81, 0xE6, 0x07, + 0x3A, 0x15, 0x0D, 0x66, 0x5F, 0x36, 0xA9, 0xAB, 0x53, 0x82, 0x47, 0x98, 0x27, 0xF2, 0x16, 0x95, + 0x05, 0x0B, 0xAE, 0xF1, 0x04, 0x92, 0x80, 0x20, 0xA4, 0x9B, 0x43, 0x66, 0x70, 0x7F, 0x45, 0x0B, + 0x4B, 0x85, 0x95, 0x10, 0x09, 0xC8, 0xD9, 0xF9, 0x5D, 0x40, 0x6D, 0x07, 0x69, 0x18, 0xF3, 0xD6, + 0x98, 0x61, 0x25, 0x8E, 0xA1, 0xE2, 0x24, 0xBD, 0xF0, 0xFA, 0x89, 0xD8, 0x68, 0xB2, 0x03, 0x81, + 0x63, 0xF9, 0x42, 0xD4, 0x1A, 0xD9, 0x4D, 0xCD, 0x30, 0x36, 0x2D, 0xB1, 0x63, 0xFC, 0xA3, 0x2B, + 0xA7, 0x07, 0x50, 0xBC, 0x67, 0xAB, 0x7D, 0x33, 0x1D, 0xEC, 0x62, 0xFE, 0xD2, 0x65, 0xAA, 0xBA, + 0x37, 0xC9, 0x7F, 0x67, 0x26, 0x9D, 0x8A, 0x8B, 0x63, 0x0B, 0xE0, 0x30, 0x65, 0x07, 0x8C, 0xF3, + 0xD1, 0xCF, 0x0D, 0xB4, 0x1E, 0xF3, 0x29, 0xBE, 0x43, 0x1F, 0x34, 0x1E, 0x52, 0x02, 0xA7, 0x8D, + 0x30, 0x2E, 0x3E, 0x39, 0x00, 0xB6, 0x7B, 0x5C, 0x29, 0x39, 0xC0, 0x0D, 0xAB, 0xA0, 0x6D, 0x77, + 0x3C, 0xB2, 0x18, 0x42, 0x57, 0x63, 0xDA, 0x9E, 0xF5, 0xE0, 0x42, 0x43, 0xF6, 0x50, 0xFD, 0x71, + 0x9B, 0x30, 0xE0, 0x92, 0x8B, 0xD1, 0xE1, 0xC4, 0x96, 0xC9, 0xF5, 0x14, 0xB6, 0xF7, 0xA5, 0x10, + 0x77, 0xF4, 0xF9, 0xAC, 0xDC, 0x45, 0xE1, 0x3C, 0xD6, 0x0B, 0xA5, 0xE2, 0x58, 0x01, 0x19, 0x39, + 0x14, 0x68, 0x96, 0xC0, 0xCE, 0xA9, 0xDE, 0x84, 0x22, 0x59, 0x87, 0x70, 0xFD, 0x8A, 0x71, 0x64, + 0x79, 0x16, 0x37, 0x80, 0x83, 0xFD, 0x9C, 0x73, 0xE6, 0x9C, 0x8B, 0xCD, 0xC0, 0x69, 0x66, 0x90, + 0x45, 0x0A, 0xC9, 0x81, 0x4A, 0xDA, 0x26, 0xDA, 0xA1, 0x70, 0x03, 0x6C, 0x36, 0x9D, 0xAD, 0xD7, + 0xE2, 0x1F, 0x27, 0xBE, 0xBB, 0xEC, 0x63, 0xD9, 0xC2, 0x2A, 0x56, 0x4D, 0x63, 0xCD, 0x92, 0xEE, + 0xAF, 0xCA, 0xD0, 0x11, 0x35, 0x2F, 0x1D, 0xF1, 0x96, 0xD1, 0xAA, 0xDC, 0xF6, 0x14, 0x3F, 0xA0, + 0xEE, 0x90, 0x83, 0x9F, 0x42, 0x40, 0xE6, 0x2C, 0x10, 0x23, 0x00, 0x23, 0x18, 0x8C, 0xA1, 0x26, + 0x4B, 0x22, 0xE1, 0x36, 0x07, 0x55, 0xCB, 0xC3, 0xD2, 0xDD, 0x12, 0x58, 0x19, 0x75, 0x03, 0xC6, + 0xD8, 0x2E, 0xCE, 0x87, 0x1C, 0xC3, 0x15, 0x44, 0x2A, 0x30, 0x00, 0x52, 0x39, 0x31, 0x13, 0xF4, + 0x25, 0x75, 0x74, 0x15, 0x6C, 0xC5, 0xC1, 0xD2, 0x33, 0x75, 0xC2, 0x41, 0x22, 0x28, 0x95, 0xDF, + 0x97, 0x6C, 0x31, 0xF8, 0x35, 0xA6, 0x54, 0x29, 0x5C, 0xF4, 0x20, 0x97, 0x69, 0xE5, 0x46, 0xFF, + 0x34, 0x24, 0x73, 0x12, 0xB8, 0x61, 0x25, 0x46, 0xB3, 0x8F, 0xBA, 0x3C, 0xFA, 0x06, 0xFF, 0x3F, + 0x66, 0x9D, 0x22, 0x55, 0x46, 0x2F, 0xFF, 0x44, 0xDB, 0x25, 0x29, 0xE0, 0x16, 0x6E, 0xEC, 0x87, + 0x97, 0x92, 0x37, 0x23, 0x0E, 0x52, 0x4E, 0xBB, 0x10, 0xBB, 0x1C, 0x73, 0x75, 0xD1, 0x31, 0xC3, + 0xAD, 0xFE, 0xB8, 0x12, 0x50, 0xA0, 0x69, 0x91, 0x36, 0xEA, 0x5F, 0x0D, 0xEC, 0x1A, 0x23, 0x4A, + 0x7D, 0x94, 0x84, 0xC8, 0x4A, 0x58, 0x6A, 0xA1, 0xA3, 0x75, 0xCA, 0x85, 0xE7, 0x96, 0x91, 0x07, + 0x05, 0x3A, 0x57, 0x61, 0x6A, 0x6F, 0xF1, 0xEF, 0xF7, 0xB3, 0xB1, 0x09, 0xB8, 0x91, 0xA8, 0xF9, + 0x57, 0xB8, 0x63, 0x95, 0xFF, 0xB4, 0x1C, 0x96, 0xE7, 0xE5, 0xEC, 0x06, 0x3A, 0x11, 0xE6, 0x81, + 0xAB, 0x23, 0xE4, 0x5E, 0x5A, 0xB6, 0x6B, 0x69, 0x62, 0x6F, 0x9D, 0xC4, 0x08, 0x6F, 0xA6, 0xBE, + 0x4D, 0x09, 0x12, 0x77, 0xCA, 0xDD, 0xB5, 0x2D, 0x66, 0xCB, 0x4F, 0x4F, 0x11, 0xF2, 0x3A, 0x1A, + 0x97, 0x1F, 0xFE, 0x50, 0x2F, 0x19, 0x32, 0x05, 0x45, 0xA0, 0x50, 0x60, 0x58, 0x40, 0x40, 0x3D, + 0xF6, 0xC3, 0x6F, 0x07, 0xC8, 0x26, 0x26, 0x0E, 0x42, 0x22, 0x96, 0x6D, 0xFE, 0x95, 0x53, 0x70, + 0xDC, 0x92, 0x12, 0x63, 0xFD, 0xA3, 0x7D, 0x6E, 0x44, 0xCD, 0x11, 0x2C, 0x51, 0x6F, 0xBC, 0x50, + 0xFC, 0x1C, 0xC8, 0x3A, 0x28, 0xF5, 0x39, 0xF8, 0x8C, 0x60, 0x5D, 0xA5, 0x4A, 0xFA, 0xAB, 0x04, + 0x7F, 0x34, 0x91, 0x53, 0xE7, 0x6C, 0x56, 0xC6, 0x14, 0xE4, 0xCC, 0xE4, 0xBB, 0x6E, 0x47, 0x7A, + 0x46, 0x6B, 0xE2, 0x88, 0xA0, 0xBD, 0xBD, 0xCC, 0x51, 0xF3, 0x37, 0x4B, 0xB3, 0xA0, 0x19, 0x92, + 0x48, 0x35, 0xBB, 0xBC, 0x79, 0x78, 0xFF, 0x49, 0xC1, 0x2B, 0x93, 0xDF, 0x75, 0xA7, 0xFB, 0x94, + 0x89, 0xAF, 0x50, 0x5E, 0x2D, 0xE1, 0x78, 0x60, 0x0C, 0xDF, 0xF8, 0x7C, 0xFD, 0xCD, 0x2D, 0xE2, + 0xFF, 0xD3, 0xA3, 0x4A, 0x48, 0x0D, 0x40, 0x8F, 0x03, 0x4F, 0x2C, 0xBD, 0xFA, 0x2E, 0x16, 0xC3, + 0xD4, 0xFD, 0x0B, 0xB3, 0xBD, 0x4F, 0x30, 0xAD, 0xD0, 0xAE, 0xCA, 0x77, 0x9D, 0xDD, 0x3D, 0xA3, + 0x66, 0xD0, 0xC1, 0x6D, 0xCC, 0x3B, 0x56, 0x81, 0x5D, 0x80, 0x07, 0xD8, 0x84, 0x46, 0x71, 0x40, + 0x57, 0xB3, 0x44, 0x85, 0x63, 0x4E, 0x17, 0x2C, 0xB0, 0x21, 0x98, 0x43, 0x42, 0x04, 0x18, 0x84, + 0xFA, 0xB1, 0xD7, 0xC5, 0x5C, 0xCA, 0x25, 0x8B, 0x1A, 0x7A, 0x50, 0x60, 0x68, 0x4A, 0x30, 0xEA, + 0xE6, 0xDE, 0x19, 0xBB, 0x9F, 0x47, 0xEF, 0xDB, 0xC5, 0x81, 0x72, 0xF0, 0x8D, 0xBA, 0x74, 0x3A, + 0xD1, 0xD5, 0xC6, 0xD1, 0xE0, 0xAE, 0x28, 0x2A, 0x65, 0xE5, 0x0B, 0x09, 0xFA, 0xEA, 0x5B, 0xA6, + 0xDB, 0x38, 0xD8, 0x67, 0xC0, 0xBE, 0xA1, 0x12, 0x1C, 0x03, 0xB1, 0x81, 0xB8, 0x95, 0xDD, 0x78, + 0xF8, 0x16, 0x6E, 0xAB, 0xBB, 0xAA, 0x33, 0x54, 0x0E, 0x39, 0x83, 0x24, 0x17, 0xB3, 0x0B, 0x3C, + 0xA1, 0x62, 0x21, 0xB2, 0xA0, 0xF8, 0x49, 0xAB, 0x8B, 0x80, 0xC6, 0x3D, 0xF1, 0x2E, 0x18, 0x44, + 0x74, 0x5F, 0x98, 0x92, 0x33, 0xFB, 0xB2, 0x52, 0x6B, 0x97, 0xE9, 0x48, 0x12, 0x91, 0x32, 0x50, + 0x21, 0x75, 0x74, 0x69, 0x88, 0x54, 0xC6, 0xF3, 0xC9, 0x37, 0x3C, 0xB3, 0x89, 0xAB, 0x33, 0x1F, + 0x79, 0x57, 0xF7, 0xE4, 0xB5, 0x87, 0x0C, 0xA4, 0x99, 0x48, 0x89, 0x63, 0x5F, 0x72, 0xA1, 0xBC, + 0xFF, 0xFE, 0xF8, 0xB3, 0xF1, 0x00, 0xE4, 0xD4, 0x01, 0x9B, 0xB7, 0x2E, 0x4F, 0xA0, 0x90, 0xE4, + 0x9B, 0x6A, 0xA8, 0xBA, 0xE1, 0xD3, 0xD5, 0xBC, 0xEB, 0xC5, 0xB2, 0x89, 0xB4, 0xE9, 0x4D, 0x3F, + 0x4C, 0xFA, 0x8C, 0xCB, 0xCD, 0x22, 0x08, 0xB8, 0xC7, 0xB3, 0xA3, 0xED, 0x6B, 0xAC, 0xF3, 0x2D, + 0x98, 0x70, 0x41, 0x47, 0x85, 0xE8, 0x6E, 0x31, 0x0A, 0xC2, 0x3E, 0x51, 0x39, 0x55, 0xF8, 0x4A, + 0xE9, 0x48, 0x64, 0x01, 0xDB, 0x8D, 0xE3, 0xAF, 0xA4, 0xB9, 0xD8, 0x19, 0xCA, 0x86, 0xCA, 0xA1, + 0x6C, 0x1C, 0x12, 0x3D, 0xA1, 0x02, 0x23, 0x1D, 0x29, 0x5D, 0x94, 0x04, 0xC6, 0x51, 0x01, 0x40, + 0x0B, 0xB3, 0x69, 0x25, 0x45, 0xEF, 0x43, 0x81, 0x4F, 0x97, 0x57, 0x0D, 0xA1, 0xA5, 0xC9, 0x9D, + 0xE6, 0x56, 0xB9, 0x38, 0x93, 0xA1, 0x78, 0xC5, 0xBF, 0x75, 0xFE, 0x81, 0x6A, 0x35, 0x64, 0x89, + 0x64, 0x43, 0x75, 0xFD, 0x29, 0x63, 0xD1, 0x15, 0xAB, 0x43, 0x60, 0x65, 0xDC, 0x98, 0xD5, 0xC7, + 0x6E, 0xF9, 0xB2, 0x38, 0xFB, 0x6E, 0xB0, 0x34, 0x9C, 0xA3, 0x73, 0x61, 0xF5, 0x51, 0xFF, 0x1F, + 0xCE, 0xB0, 0x08, 0x83, 0x29, 0xB3, 0x82, 0x07, 0xFA, 0xC4, 0xE5, 0x21, 0xD3, 0xA0, 0xD4, 0xC0, + 0xF8, 0x1A, 0x65, 0x9B, 0x35, 0x7A, 0xE3, 0x32, 0xA5, 0x4D, 0x77, 0x1F, 0x23, 0x19, 0xCC, 0xE1, + 0xB3, 0x50, 0x0D, 0xE8, 0x2F, 0x8B, 0x18, 0x89, 0x61, 0xCB, 0x22, 0xBA, 0xE0, 0x4A, 0xA2, 0x7F, + 0xA5, 0x1B, 0x45, 0x59, 0x33, 0xC4, 0x73, 0xDF, 0x42, 0xC6, 0x00, 0x11, 0x37, 0xF2, 0x3C, 0x1B, + 0xF4, 0x26, 0xD1, 0x6D, 0x93, 0xC1, 0x94, 0xD2, 0x60, 0xE5, 0xF3, 0x91, 0x66, 0x92, 0x3C, 0x65, + 0x27, 0xC1, 0x83, 0x13, 0x76, 0x5A, 0x88, 0xEC, 0xB2, 0x59, 0x95, 0x18, 0x81, 0x2E, 0x94, 0x96, + 0x53, 0x17, 0xB6, 0xFD, 0x8C, 0xCC, 0xBE, 0x8D, 0x36, 0xB3, 0xC8, 0xF2, 0xB2, 0xBE, 0x0F, 0x12, + 0x99, 0xFF, 0xFA, 0xF9, 0x18, 0xAB, 0x30, 0xFA, 0xB1, 0x5B, 0xF2, 0xEE, 0xCA, 0x6E, 0xA1, 0xD9, + 0xCE, 0xCC, 0x60, 0xA0, 0x4D, 0xFD, 0x7C, 0xAD, 0x4D, 0x50, 0xB6, 0x88, 0x0D, 0x88, 0x3B, 0x28, + 0x7F, 0xA1, 0x28, 0x41, 0x0A, 0x43, 0xAD, 0xCC, 0x08, 0x14, 0xF3, 0xF2, 0x43, 0xE7, 0xCF, 0x6A, + 0x5C, 0x11, 0xD0, 0x6D, 0x99, 0xC8, 0x4F, 0xB1, 0x14, 0x06, 0xBC, 0x68, 0x6D, 0xBE, 0xCD, 0xD7, + 0x58, 0xA2, 0x17, 0xF5, 0x9E, 0xFD, 0xDA, 0xFA, 0xBF, 0x73, 0x57, 0x4A, 0xF8, 0xF3, 0xA9, 0x94, + 0xB3, 0x01, 0xE9, 0xA3, 0xDA, 0xEA, 0xC1, 0x40, 0x33, 0xAA, 0x3F, 0xE6, 0x0D, 0x6A, 0xE2, 0xF3, + 0x74, 0xE8, 0x1B, 0x3C, 0x2B, 0x25, 0x44, 0x8E, 0x1C, 0x36, 0xBE, 0xA9, 0x27, 0x6E, 0x6A, 0x48, + 0x8E, 0x2F, 0x2C, 0x9D, 0x71, 0x66, 0x23, 0x7C, 0x7A, 0x74, 0x93, 0x46, 0x2D, 0xCA, 0x6B, 0xC6, + 0x33, 0xDA, 0x1E, 0x1E, 0x44, 0x07, 0xFD, 0x89, 0x5D, 0x30, 0x02, 0x4C, 0xB1, 0x73, 0xC0, 0x91, + 0xEB, 0xA5, 0x61, 0x89, 0xA4, 0x04, 0xFD, 0xD5, 0x5F, 0x54, 0x59, 0x81, 0xC3, 0x2A, 0x13, 0x89, + 0xDA, 0x68, 0xB6, 0x3A, 0x9C, 0x70, 0x6F, 0x48, 0xB4, 0x3C, 0xF8, 0x9B, 0xF8, 0xF2, 0x59, 0xBF, + 0xF4, 0x8D, 0x06, 0x58, 0xEA, 0xA2, 0xA6, 0xB4, 0x70, 0x08, 0x80, 0x2B, 0x50, 0x13, 0x36, 0x79, + 0x17, 0x0B, 0x94, 0x0E, 0x4D, 0xF5, 0xC8, 0x14, 0xB9, 0x02, 0x7D, 0xEE, 0x6B, 0xBD, 0x10, 0xB4, + 0x85, 0x74, 0xA1, 0xB9, 0x84, 0x67, 0xC6, 0x2C, 0xDB, 0xDA, 0x55, 0x54, 0x16, 0xDA, 0x02, 0xB6, + 0xDA, 0x2A, 0x9B, 0x51, 0xD6, 0xDC, 0x87, 0x80, 0xC1, 0xB8, 0x6F, 0x0C, 0xEF, 0x4B, 0xD1, 0x1A, + 0x9F, 0x36, 0x2E, 0x9C, 0x7E, 0x5F, 0x17, 0xE2, 0xC1, 0x82, 0x0C, 0x42, 0x0D, 0x15, 0x18, 0xCA, + } + }; + } +} diff --git a/DanhengKcpSharp/DanhengConnection.cs b/DanhengKcpSharp/DanhengConnection.cs index e9ff980f..6aeb1b3c 100644 --- a/DanhengKcpSharp/DanhengConnection.cs +++ b/DanhengKcpSharp/DanhengConnection.cs @@ -30,11 +30,20 @@ public class DanhengConnection public bool IsOnline = true; public StreamWriter? Writer; + public byte[]? XorKey { get; set; } + public ulong ClientSecretKeySeed { get; set; } + public DanhengConnection(KcpConversation conversation, IPEndPoint remote) { Conversation = conversation; RemoteEndPoint = remote; CancelToken = new CancellationTokenSource(); + if (ConfigManager.Config.GameServer.UsePacketEncryption) + { +#pragma warning disable CS8602 // CS8602 - Dereference of a possibly null reference. + XorKey = Crypto.ClientSecretKey.GetXorKey(); +#pragma warning restore CS8602 // CS8602 - Dereference of a possibly null reference. + } Start(); } @@ -123,6 +132,8 @@ public class DanhengConnection { try { + if (ConfigManager.Config.GameServer.UsePacketEncryption) + Crypto.Xor(packet, XorKey); _ = await Conversation.SendAsync(packet, CancelToken.Token); } catch @@ -148,7 +159,8 @@ public class DanhengConnection try { - _ = await Conversation.SendAsync(packetBytes, CancelToken.Token); + //_ = await Conversation.SendAsync(packetBytes, CancelToken.Token); + await SendPacket(packetBytes); } catch { diff --git a/GameServer/Server/Connection.cs b/GameServer/Server/Connection.cs index c8420f0b..6572dbf2 100644 --- a/GameServer/Server/Connection.cs +++ b/GameServer/Server/Connection.cs @@ -78,6 +78,8 @@ public class Connection(KcpConversation conversation, IPEndPoint remote) : Danhe private async Task ProcessMessageAsync(Memory data) { var gamePacket = data.ToArray(); + if (ConfigManager.Config.GameServer.UsePacketEncryption) + Crypto.Xor(gamePacket, XorKey); await using MemoryStream ms = new(gamePacket); using BinaryReader br = new(ms); diff --git a/GameServer/Server/Packet/Recv/Player/HandlerPlayerGetTokenCsReq.cs b/GameServer/Server/Packet/Recv/Player/HandlerPlayerGetTokenCsReq.cs index c819c3e8..39cc817c 100644 --- a/GameServer/Server/Packet/Recv/Player/HandlerPlayerGetTokenCsReq.cs +++ b/GameServer/Server/Packet/Recv/Player/HandlerPlayerGetTokenCsReq.cs @@ -13,6 +13,7 @@ namespace EggLink.DanhengServer.GameServer.Server.Packet.Recv.Player; [Opcode(CmdIds.PlayerGetTokenCsReq)] public class HandlerPlayerGetTokenCsReq : Handler { + Logger logger = new Logger("GameServer"); public override async Task OnHandle(Connection connection, byte[] header, byte[] data) { var req = PlayerGetTokenCsReq.Parser.ParseFrom(data); @@ -46,5 +47,11 @@ public class HandlerPlayerGetTokenCsReq : Handler await connection.Player.OnGetToken(); connection.Player.Connection = connection; await connection.SendPacket(new PacketPlayerGetTokenScRsp(connection)); + + if (ConfigManager.Config.GameServer.UsePacketEncryption) + { + connection.XorKey = Crypto.GenerateXorKey(connection.ClientSecretKeySeed); + logger.Info($"{connection.RemoteEndPoint.ToString()} key exchange successful"); + } } } \ No newline at end of file diff --git a/GameServer/Server/Packet/Send/Player/PacketPlayerGetTokenScRsp.cs b/GameServer/Server/Packet/Send/Player/PacketPlayerGetTokenScRsp.cs index 1516ebe1..2f7dc381 100644 --- a/GameServer/Server/Packet/Send/Player/PacketPlayerGetTokenScRsp.cs +++ b/GameServer/Server/Packet/Send/Player/PacketPlayerGetTokenScRsp.cs @@ -1,5 +1,7 @@ using EggLink.DanhengServer.Kcp; using EggLink.DanhengServer.Proto; +using EggLink.DanhengServer.Util; +using EggLink.DanhengServer.Util.Security; namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.Player; @@ -13,6 +15,12 @@ public class PacketPlayerGetTokenScRsp : BasePacket Uid = (uint)(connection.Player?.Uid ?? 0) }; + if (ConfigManager.Config.GameServer.UsePacketEncryption) + { + MT19937 tempRandom = new MT19937((ulong)DateTimeOffset.Now.ToUnixTimeSeconds()); + rsp.SecretKeySeed = connection.ClientSecretKeySeed = tempRandom.NextUInt64(); + } + SetData(rsp); } diff --git a/Program/Program/EntryPoint.cs b/Program/Program/EntryPoint.cs index d1407ee2..2f37473a 100644 --- a/Program/Program/EntryPoint.cs +++ b/Program/Program/EntryPoint.cs @@ -100,7 +100,6 @@ public class EntryPoint Logger.Info(I18NManager.Translate("Server.ServerInfo.LoadedItem", I18NManager.Translate("Word.DatabaseAccount"))); - Logger.Warn(I18NManager.Translate("Server.ServerInfo.WaitForAllDone")); } catch (Exception e) { @@ -111,7 +110,16 @@ public class EntryPoint } HandlerManager.Init(); + if (ConfigManager.Config.GameServer.UsePacketEncryption) + { + Crypto.ClientSecretKey = Crypto.InitEc2b(); + if (Crypto.ClientSecretKey == null) + { + ConfigManager.Config.GameServer.UsePacketEncryption = false; + } + } + Logger.Warn(I18NManager.Translate("Server.ServerInfo.WaitForAllDone")); WebProgram.Main([], GetConfig().HttpServer.Port, GetConfig().HttpServer.GetBindDisplayAddress()); Logger.Info(I18NManager.Translate("Server.ServerInfo.ServerRunning", I18NManager.Translate("Word.Dispatch"), GetConfig().HttpServer.GetDisplayAddress())); diff --git a/WebServer/Handler/QueryGatewayHandler.cs b/WebServer/Handler/QueryGatewayHandler.cs index d4242461..8742e6f2 100644 --- a/WebServer/Handler/QueryGatewayHandler.cs +++ b/WebServer/Handler/QueryGatewayHandler.cs @@ -31,6 +31,8 @@ internal class QueryGatewayHandler Unk6 = true, Unk7 = true }; + if (ConfigManager.Config.GameServer.UsePacketEncryption) + gateServer.ClientSecretKey = Convert.ToBase64String(Crypto.ClientSecretKey.GetBytes()); if (!ResourceManager.IsLoaded) gateServer.Retcode = 2;