Пример #1
0
        // verified
        private static ListOfDiffPairs UndoLastRound(ListOfDiffPairs diffPairs, UInt32 subKey)
        {
            var result = new ListOfDiffPairs();

            for (var i = 0; i < numberOfPlain; ++i)
            {
                UInt32 firstCipherLeft  = Feal4Helper.GetLeftHalf(diffPairs[i].Item1.Cipher);
                UInt32 firstCipherRight = Feal4Helper.GetRightHalf(diffPairs[i].Item1.Cipher);

                UInt32 secondCipherLeft  = Feal4Helper.GetLeftHalf(diffPairs[i].Item2.Cipher);
                UInt32 secondCipherRight = Feal4Helper.GetRightHalf(diffPairs[i].Item2.Cipher);

                firstCipherLeft  = firstCipherRight;
                secondCipherLeft = secondCipherRight;

                firstCipherRight  = Feal4Helper.Fbox(firstCipherLeft ^ subKey) ^ (Feal4Helper.GetLeftHalf(diffPairs[i].Item1.Cipher));
                secondCipherRight = Feal4Helper.Fbox(secondCipherLeft ^ subKey) ^ (Feal4Helper.GetLeftHalf(diffPairs[i].Item2.Cipher));

                var firstObj = new PlainCipherPair <UInt64>(diffPairs[i].Item1.Plain,
                                                            Feal4Helper.Combine32BitHalfs(firstCipherLeft, firstCipherRight));
                var secondObj = new PlainCipherPair <UInt64>(diffPairs[i].Item2.Plain,
                                                             Feal4Helper.Combine32BitHalfs(secondCipherLeft, secondCipherRight));

                result.Add(Tuple.Create(firstObj, secondObj));
            }
            return(result);
        }
Пример #2
0
        public void TestCombine32BitHalfs()
        {
            const UInt32 leftHalf       = 0b11010101111111110110101000001000;
            const UInt32 rightHalf      = 0b00010000010101101111111110101011;
            const UInt64 expectedResult = 0b1101010111111111011010100000100000010000010101101111111110101011;

            Feal4Helper.Combine32BitHalfs(leftHalf, rightHalf).Should().Be(expectedResult);
        }
Пример #3
0
        public void TestRotateLeft()
        {
            const byte value           = (byte)(0b10111101);
            const byte expectedRotated = (byte)(0b11110110);
            var        actualRotated   = Feal4Helper.Rotl2(value);

            actualRotated.Should().Be(expectedRotated);
        }
Пример #4
0
        public void TestCombineBytes()
        {
            const byte zeroByte   = 0b00001000;
            const byte firstByte  = 0b01101010;
            const byte secondByte = 0b11111111;
            const byte thirdByte  = 0b11010101;

            Feal4Helper.CombineBytes(thirdByte, secondByte, firstByte, zeroByte).Should()
            .Be(0b11010101111111110110101000001000);
        }
Пример #5
0
        public void TestGetNthByte()
        {
            const UInt32 value              = 0b11010101111111110110101000001000;
            const byte   expectedZeroByte   = 0b00001000;
            const byte   expectedFirstByte  = 0b01101010;
            const byte   expectedSecondByte = 0b11111111;
            const byte   expectedThirdByte  = 0b11010101;

            Feal4Helper.GetNthByte(value, 0).Should().Be(expectedZeroByte);
            Feal4Helper.GetNthByte(value, 1).Should().Be(expectedFirstByte);
            Feal4Helper.GetNthByte(value, 2).Should().Be(expectedSecondByte);
            Feal4Helper.GetNthByte(value, 3).Should().Be(expectedThirdByte);
        }
Пример #6
0
        // verified
        private static int GetScore(UInt32 outDiff, ListOfDiffPairs chosenPlaintexts,
                                    UInt32 fakeK32)
        {
            var score = 0;

            for (var i = 0; i < numberOfPlain; ++i)
            {
                var cipherLeft = Feal4Helper.GetLeftHalf(chosenPlaintexts[i].Item1.Cipher) ^
                                 Feal4Helper.GetLeftHalf(chosenPlaintexts[i].Item2.Cipher);
                var cipherRight = Feal4Helper.GetRightHalf(chosenPlaintexts[i].Item1.Cipher) ^
                                  Feal4Helper.GetRightHalf(chosenPlaintexts[i].Item2.Cipher);

                var y = cipherRight;
                var z = cipherLeft ^ outDiff;

                var firstFakeLeft =
                    Feal4Helper.GetLeftHalf(chosenPlaintexts[i].Item1.Cipher);
                var firstFakeRight =
                    Feal4Helper.GetRightHalf(chosenPlaintexts[i].Item1.Cipher);
                var secondFakeLeft =
                    Feal4Helper.GetLeftHalf(chosenPlaintexts[i].Item2.Cipher);
                var secondFakeRight =
                    Feal4Helper.GetRightHalf(chosenPlaintexts[i].Item2.Cipher);

                var y0 = firstFakeRight;
                var y1 = secondFakeRight;

                var fakeInput0 = y0 ^ fakeK32;
                var fakeInput1 = y1 ^ fakeK32;

                var fakeOut0 = Feal4Helper.Fbox(fakeInput0);
                var fakeOut1 = Feal4Helper.Fbox(fakeInput1);
                var fakeDiff = fakeOut0 ^ fakeOut1;

                if (fakeDiff == z)
                {
                    ++score;
                }
                else
                {
                    break;
                }
            }
            return(score);
        }
Пример #7
0
        // verified
        private ListOfDiffPairs UndoFinalOperation(ListOfDiffPairs data)
        {
            var result = new ListOfDiffPairs();

            foreach (var item in data)
            {
                var firstLeftCipher  = Feal4Helper.GetLeftHalf(item.Item1.Cipher);
                var firstRightCipher = Feal4Helper.GetRightHalf(item.Item1.Cipher) ^ firstLeftCipher;

                var secondLeftCipher  = Feal4Helper.GetLeftHalf(item.Item2.Cipher);
                var secondRightCipher = Feal4Helper.GetRightHalf(item.Item2.Cipher) ^ secondLeftCipher;

                var firstRecombined  = Feal4Helper.Combine32BitHalfs(firstLeftCipher, firstRightCipher);
                var secondRecombined = Feal4Helper.Combine32BitHalfs(secondLeftCipher, secondRightCipher);

                var firstObj  = new PlainCipherPair64(item.Item1.Plain, firstRecombined);
                var secondObj = new PlainCipherPair64(item.Item2.Plain, secondRecombined);
                result.Add(Tuple.Create(firstObj, secondObj));
            }
            return(result);
        }
Пример #8
0
        public void TestGetRightHalf()
        {
            const UInt64 value = 0b1101010111111111011010100000100000010000010101101111111110101011;

            Feal4Helper.GetRightHalf(value).Should().Be(0b00010000010101101111111110101011);
        }
Пример #9
0
        public UInt32[] Analyze()
        {
            var commonStopWatch = Stopwatch.StartNew();

            Console.WriteLine("CRACKING ROUND 4");
            var fourthRoundStopWatch            = Stopwatch.StartNew();
            var fourthRoundChosenPlaintexts     = GetChosenPlaintexts(inputDiff1);
            var fourthRoundUndoneFinalOperation = UndoFinalOperation(fourthRoundChosenPlaintexts);
            //for (var i = 0; i < fourthRoundUndoneFinalOperation.Count; ++i)
            //    Console.WriteLine(fourthRoundUndoneFinalOperation[i].Item1.Cipher);
            var fourthRoundSubKey = CrackLastRound(outputDiff, fourthRoundUndoneFinalOperation);

            Console.WriteLine($"4-th round cracking time: {fourthRoundStopWatch.Elapsed}");
            Console.WriteLine($"4-th round subkey: {fourthRoundSubKey}");


            Console.WriteLine("CRACKING ROUND 3");
            var thirdRoundStopWatch            = Stopwatch.StartNew();
            var thirdRoundChosenPlaintexts     = GetChosenPlaintexts(inputDiff2);
            var thirdRoundUndoneFinalOperation = UndoFinalOperation(thirdRoundChosenPlaintexts);
            var thirdRoundUndoneLastRound      = UndoLastRound(thirdRoundUndoneFinalOperation, fourthRoundSubKey);
            var thirdRoundSubKey = CrackLastRound(outputDiff, thirdRoundUndoneLastRound);

            Console.WriteLine($"3-th round cracking time: {thirdRoundStopWatch.Elapsed}");

            Console.WriteLine("CRACKING ROUND 2");
            var secondRoundStopWatch            = Stopwatch.StartNew();
            var secondRoundChosenPlaintexts     = GetChosenPlaintexts(inputDiff3);
            var secondRoundUndoneFinalOperation = UndoFinalOperation(secondRoundChosenPlaintexts);
            var secondRoundUndoneLastRound      = UndoLastRound(secondRoundUndoneFinalOperation, fourthRoundSubKey);
            var secondRoundUndonePrevLastRound  = UndoLastRound(secondRoundUndoneLastRound, thirdRoundSubKey);
            var secondRoundSubKey = CrackLastRound(outputDiff, secondRoundUndonePrevLastRound);

            Console.WriteLine($"2-th round cracking time: {secondRoundStopWatch.Elapsed}");

            Console.WriteLine("CRACKING ROUND 1");
            var firstRoundStopWatch     = Stopwatch.StartNew();
            var firstRoundUndoLastRound = UndoLastRound(secondRoundUndonePrevLastRound, secondRoundSubKey);

            UInt32 crackedSubKey0 = 0;
            UInt32 crackedSubKey4 = 0;
            UInt32 crackedSubKey5 = 0;

            for (UInt64 guessK0 = 0; guessK0 < (UInt64)UInt32.MaxValue; ++guessK0)
            {
                var    guessK032 = (UInt32)guessK0;
                UInt32 guessK4   = 0;
                UInt32 guessK5   = 0;

                for (var i = 0; i < numberOfPlain; ++i)
                {
                    var firstPlainLeft = Feal4Helper.GetLeftHalf(
                        firstRoundUndoLastRound[i].Item1.Plain);
                    var firstPlainRight = Feal4Helper.GetRightHalf(
                        firstRoundUndoLastRound[i].Item1.Plain);
                    var firstCipherLeft = Feal4Helper.GetLeftHalf(
                        firstRoundUndoLastRound[i].Item1.Cipher);
                    var firstCipherRight = Feal4Helper.GetRightHalf(
                        firstRoundUndoLastRound[i].Item1.Cipher);
                    var tempY0 =
                        Feal4Helper.Fbox(firstCipherRight ^ guessK032) ^ firstCipherLeft;
                    if (guessK4 == 0)
                    {
                        guessK4 = tempY0 ^ firstPlainLeft;
                        guessK5 = tempY0 ^ firstCipherRight ^ firstPlainRight;
                    }
                    else if (((tempY0 ^ firstPlainLeft) != guessK4) ||
                             ((tempY0 ^ firstCipherRight ^ firstPlainRight) != guessK5))
                    {
                        guessK4 = 0;
                        guessK5 = 0;
                        break;
                    }
                }

                if (guessK4 != 0)
                {
                    crackedSubKey0 = guessK032;
                    crackedSubKey4 = guessK4;
                    crackedSubKey5 = guessK5;
                    break;
                }
            }
            Console.WriteLine($"1-th round cracking time: {firstRoundStopWatch.Elapsed}");
            Console.WriteLine($"Overall elapsed time: {commonStopWatch.Elapsed}");

            if (subKeys[0] == crackedSubKey0)
            {
                Console.WriteLine("0-th subkey GOOD");
            }
            if (subKeys[1] == secondRoundSubKey)
            {
                Console.WriteLine("1-th subkey GOOD");
            }
            if (subKeys[2] == thirdRoundSubKey)
            {
                Console.WriteLine("2-th subkey GOOD");
            }
            if (subKeys[3] == fourthRoundSubKey)
            {
                Console.WriteLine("3-th subkey GOOD");
            }
            if (subKeys[4] == crackedSubKey4)
            {
                Console.WriteLine("4-th subkey GOOD");
            }
            if (subKeys[5] == crackedSubKey5)
            {
                Console.WriteLine("5-th subkey GOOD");
            }

            return(new[]
            {
                crackedSubKey0, secondRoundSubKey, thirdRoundSubKey,
                fourthRoundSubKey, crackedSubKey4, crackedSubKey5
            });
        }