Example #1
0
        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);
        }
Example #2
0
        static void Main(string[] args)
        {
//			ProofOfConecpt.Do();
//			return;

            if (args.Length < 1)
            {
                Console.WriteLine("Usage: sploit.exe <fileToDecrypt> [expectedKey]");
                Environment.Exit(1);
            }

            var expectedKey = args.Length >= 2 ? File.ReadAllBytes(args[1]) : new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

            byte[] imageBytes;
            try
            {
                imageBytes = File.ReadAllBytes(args[0]);
            }
            catch (Exception e)
            {
                Console.WriteLine($"Can't read data from file {args[0]}", e);
                Environment.Exit(1);
                return;
            }

            var spn = new SubstitutionPermutationNetwork(SubstitutionPermutationNetwork.GenerateRandomKey());

            var pairs  = GeneratePlainEncryptedPairs(imageBytes);
            var plains = pairs.Select(tuple => tuple.Item1).ToArray();
            var encs   = pairs.Select(tuple => tuple.Item2).ToArray();

            var linearCryptoanalysis    = new LinearCryptoanalysis(spn);
            var bestLayerApproximations = linearCryptoanalysis.ChooseBestPathsStartingFromSingleSBoxInRound0(Exploit.maxSBoxesInLastRound, Exploit.maxSBoxesInRound, Exploit.thresholdBias).ToList();

            Console.WriteLine($"Total approximations: {bestLayerApproximations.Count}");

            var solutions = new List <Solution>();

            foreach (var approximationsGroup in bestLayerApproximations
                     .Where(layer => layer.round0sboxNum % 8 == 3 || (layer.round0sboxNum % 8 == 4 && ((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(6))
                {
                    solutions.AddRange(Exploit.HackApproximation(plains, encs, approximation, expectedKey));
                }
            }

            var solutionsDict = Exploit.OrderSolutions(solutions, expectedKey);

            var imageLength = imageBytes.Length - SubstitutionPermutationNetwork.GenerateRandomIV().Length;

            if (imageLength >= 65536)
            {
                throw new Exception("Unexpected image ciphertext length");
            }

            Console.WriteLine("\nBruting left bits..");

            var plaintextPrefixFrom4 = new byte[] { 0, 0, 0, 0, 0, 0, 0x36, 0, 0, 0 };
            var hackedKey            = GetFinalSolution(solutionsDict, imageBytes.Take(24).ToArray(), plaintextPrefixFrom4);

            if (hackedKey != null)
            {
                Console.WriteLine($"\nHACKED KEY: {hackedKey.ToHexUpperCase()}");
            }
            else
            {
                Console.WriteLine("BAD LUCK. Key not hacked");
            }
        }
Example #3
0
        public static List <Solution> HackApproximation(byte[][] plains, byte[][] encs, Layer bestLayerApproximation, byte[] expectedKey)
        {
            int iterationsCount = plains.Length;

            Console.WriteLine($"\nBEST OPTION: round0sboxNum {bestLayerApproximation.round0sboxNum}\tround0x {bestLayerApproximation.round0x}\tround0y {bestLayerApproximation.round0y}\tbias {bestLayerApproximation.inputProbability.Bias()}\toutSBoxes {string.Join(",", bestLayerApproximation.ActivatedSboxesNums)}\tLastRoundInputBits {SubstitutionPermutationNetwork.GetBitString(bestLayerApproximation.inputBits)}");

            var targetPartialSubkeys = GenerateTargetPartialSubkeys(bestLayerApproximation.ActivatedSboxesNums)
                                       .Select(targetPartialSubkey => (targetPartialSubkey, SubstitutionPermutationNetwork.GetBytesBigEndian(targetPartialSubkey)))
                                       .ToList();

            var keyProbabilities = targetPartialSubkeys
                                   .ToDictionary(u => u.Item1, u => 0);
            var hackingSubstitutionPermutationNetwork = new SubstitutionPermutationNetwork(SubstitutionPermutationNetwork.GenerateRandomKey());

            for (int i = 0; i < plains.Length; i++)
            {
                if (i > 0 && i % (plains.Length / 4) == 0)
                {
                    Console.WriteLine($" done {i} iterations of {iterationsCount}");
                }

                var plain = plains[i];
                var enc   = encs[i];

                HackIteration(plain, enc, bestLayerApproximation.round0sboxNum, bestLayerApproximation.round0x, bestLayerApproximation.inputBits, targetPartialSubkeys, hackingSubstitutionPermutationNetwork, keyProbabilities);
            }

            return(GetSolutions(bestLayerApproximation, keyProbabilities, expectedKey, iterationsCount));
        }