public static byte[][] GenerateSubTables() { var rows = new byte[0x100][]; for (int i = 0; i < 0x100; i++) { rows[i] = CriHcaKey.CreateRandomRow((byte)i); } return(rows); }
/// <summary> /// Finds possible tables used to shuffle the decryption table with a known upper seed /// </summary> /// <remarks> /// As in <see cref="FilterPossibleShufflersWithByte2Zeros"/>, we search each possible shuffle table /// to find one with at least 9 rows of all zeros. The difference is this time we know which specific /// rows need to be all zeros, the rows containing the upper nibbles 7 through 0xf. /// The two shuffler IDs correspond to the positions of the bytes 0 or 0xFF in the table, so this is /// used to further filter the possible shufflers. /// </remarks> public void FindShuffleTable() { byte[] upperSubTable = SubTables[UpperSeed]; byte[] inverseSubTable = CriHcaKey.InvertTable(upperSubTable); int[] count = new int[16]; var possibleShufflers = new List <ShufflerId>(); byte row0 = inverseSubTable[0]; byte rowF = inverseSubTable[0xf]; foreach (var s in PossibleShufflers) { // Count the number of zeros in each row Array.Clear(count, 0, 16); foreach (byte v in Byte2Zeros) { int unshuffledUpperNibble = BackwardShuffle[s.Pos1][s.Pos2][v] >> 4; count[unshuffledUpperNibble]++; } bool valid = true; // Invalidate the tables without the required empty rows for (int i = 0; i < upperSubTable.Length; i++) { for (int j = 7; j < 15; j++) { if (count[inverseSubTable[j]] < 16) { valid = false; } } if (count[inverseSubTable[15]] < 15) { valid = false; } } // Invalidate the tables without the bytes 0x00 and 0xFF in their proper rows if ((s.Pos1 >> 4 != row0 && s.Pos1 >> 4 != rowF) || (s.Pos2 >> 4 != row0 && s.Pos2 >> 4 != rowF) || s.Pos1 >> 4 == s.Pos2 >> 4) { valid = false; } if (valid) { possibleShufflers.Add(s); } } PossibleShufflers = possibleShufflers; }
public static byte[] GenerateShuffler(int a, int b, bool backward) { byte[] table = new byte[256]; byte x = 0; int outPos = 1; for (int i = 0; i < 256; i++) { x += 17; if (x != a && x != b) { table[outPos++] = x; } } return(backward ? table : CriHcaKey.InvertTable(table)); }