public static void DecryptPass(uint seed, Span <byte> input, Span <byte> output, int size) { uint one = CRC32.CRC32UInt(seed); uint two = CRC32.CRC32UInt(one); uint three = CRC32.CRC32UInt(two); uint four = CRC32.CRC32UInt(three); if (size == 0) { return; } // CryptDataChunk one &= 0x1ffff; two &= 0x7ffff; three &= 0x7fffff; four &= 0x1fffffff; for (int i = 0; i < size; i++) { output[i] = (byte)((byte)three ^ (byte)four ^ (byte)one ^ (byte)two ^ input[i]); one = (one & 0xff) << 0x9 | one >> 0x08; two = (two & 0xff) << 0xb | two >> 0x08; three = (three & 0xff) << 0xf | three >> 0x08; four = (four & 0xff) << 0x15 | four >> 0x08; } }
public static uint CRCXor(Span <uint> input, uint input2) { uint crc = CRC32.CRC32UInt(input2); uint old = input[0]; input[0] ^= crc; return(old); }
/// <summary> /// Key computing GT5P JP Demo /// </summary> /// <param name="seed"></param> /// <returns></returns> private uint[] PrepareKeyOld(uint seed) { var keysetSeedCrc = ~CRC32.CRC32_0x04C11DB7(_keys.Magic, 0); uint one = CRC32.CRC32UInt(seed ^ keysetSeedCrc); uint two = CRC32.CRC32UInt(one); uint three = CRC32.CRC32UInt(two); uint four = CRC32.CRC32UInt(three); uint[] keys = new uint[4]; keys[0] = one & 0x1FFFF; keys[1] = two & 0x7ffff; keys[2] = three & 0x7fffff; keys[3] = four & 0x1fffffff; return(keys); }