private static void HackCipher(SubstitutionPermutationNetwork spn, byte[] expectedKey, int iterationsCount) { var linearCryptoanalysis = new LinearCryptoanalysis(spn); var bestLayerApproximations = linearCryptoanalysis.ChooseBestPathsStartingFromSingleSBoxInRound0(Exploit.maxSBoxesInLastRound, Exploit.maxSBoxesInRound, Exploit.thresholdBias).ToList(); Console.WriteLine($"Total approximations: {bestLayerApproximations.Count}"); var plains = Enumerable.Range(0, iterationsCount).Select(i => GenerateRandomPlainText()).ToArray(); var encs = plains.Select(plain => spn.EncryptBlock(plain)).ToArray(); var solutions = new List <Solution>(); foreach (var approximationsGroup in bestLayerApproximations .Where(layer => layer.round0sboxNum % 8 == 6 || (layer.round0sboxNum % 8 == 7 && ((layer.round0x & 0x01) == 0))) .GroupBy(layer => layer.ActivatedSboxesNums.Aggregate("", (s, num) => s + num)) .OrderBy(group => group.Key)) { foreach (var approximation in approximationsGroup.Distinct().OrderByDescending(layer => layer.inputProbability.Bias()).Take(3)) { solutions.AddRange(Exploit.HackApproximation(plains, encs, approximation, expectedKey)); } } Exploit.OrderSolutions(solutions, expectedKey); }
public static void Do() { Console.WriteLine($"SPN: rounds {SubstitutionPermutationNetwork.RoundsCount}, blocksize {SubstitutionPermutationNetwork.BlockSizeBytes * 8 } bits"); var expectedKey = SubstitutionPermutationNetwork.GenerateRandomKey(); Console.WriteLine($"key: {expectedKey.ToHexUpperCase()}"); var spn = new SubstitutionPermutationNetwork(expectedKey); var plainTextString = new string('X', SubstitutionPermutationNetwork.BlockSizeBytes); var plainText = Encoding.ASCII.GetBytes(plainTextString); var encryptedBytes = spn.EncryptBlock(plainText); var decryptedBytes = spn.DecryptBlock(encryptedBytes); var decryptedString = Encoding.ASCII.GetString(decryptedBytes); Console.WriteLine($"{plainTextString} -> {encryptedBytes.ToHexUpperCase()} -> {decryptedString}"); HackCipher(spn, expectedKey, 6000); }