Пример #1
0
        private Characteristic FindBestCharacteristic(int round, List <Differential> differentialsList, int outputDiff, Characteristic res)
        {
            //end of rekursion
            if (round == 0)
            {
                return(res);
            }

            //contains the active SBoxes in the round
            bool[] activeSBoxes = new bool[CipherThreeConfiguration.SBOXNUM];

            //check active SBoxes
            int[] outputDiffs = new int[CipherThreeConfiguration.SBOXNUM];
            for (int i = 0; i < CipherThreeConfiguration.SBOXNUM; i++)
            {
                outputDiffs[i] = GetSubBlockFromBlock(outputDiff, i);
                if (outputDiffs[i] > 0)
                {
                    activeSBoxes[i] = true;
                }
                else
                {
                    activeSBoxes[i] = false;
                }
            }

            //resultList
            List <Characteristic> diffList = new List <Characteristic>();

            //prepare the arrayOfDifferentialLists
            List <Differential>[] arrayOfDifferentialLists = new List <Differential> [CipherThreeConfiguration.SBOXNUM];
            int comb = 1;

            for (int b = 0; b < CipherThreeConfiguration.SBOXNUM; b++)
            {
                if (activeSBoxes[b])
                {
                    arrayOfDifferentialLists[b] = new List <Differential>(differentialsList.Count);
                    differentialsList.ForEach((item) =>
                    {
                        arrayOfDifferentialLists[b].Add((Differential)item.Clone());
                    });

                    List <Differential> diffsToRemove = new List <Differential>();
                    for (int j = 0; j < arrayOfDifferentialLists[b].Count; j++)
                    {
                        if (arrayOfDifferentialLists[b][j].OutputDifferential != outputDiffs[b])
                        {
                            diffsToRemove.Add(arrayOfDifferentialLists[b][j]);
                        }
                    }

                    foreach (var curDiff in diffsToRemove)
                    {
                        arrayOfDifferentialLists[b].Remove(curDiff);
                    }

                    comb *= arrayOfDifferentialLists[b].Count;
                }
                else
                {
                    arrayOfDifferentialLists[b] = new List <Differential>();
                }
            }

            for (int c = 0; c < comb; c++)
            {
                Differential[] curDiffSBoxes = new Differential[CipherThreeConfiguration.SBOXNUM];

                //calc indices
                int indexNo = 0;
                int j       = c;
                while (j > 0)
                {
                    if (arrayOfDifferentialLists[indexNo].Count > 0)
                    {
                        int index = j % arrayOfDifferentialLists[indexNo].Count;
                        j = j / arrayOfDifferentialLists[indexNo].Count;
                        curDiffSBoxes[indexNo] = arrayOfDifferentialLists[indexNo][index];
                    }
                    indexNo++;
                }

                //zero case
                if (c == 0)
                {
                    for (int i = 0; i < CipherThreeConfiguration.SBOXNUM; i++)
                    {
                        if (activeSBoxes[i])
                        {
                            curDiffSBoxes[i] = arrayOfDifferentialLists[i][0];
                        }
                    }
                }

                //check null values
                for (int z = 0; z < CipherThreeConfiguration.SBOXNUM; z++)
                {
                    if (curDiffSBoxes[z] == null)
                    {
                        curDiffSBoxes[z] = new Differential()
                        {
                            Count              = 0,
                            InputDifferential  = 0,
                            OutputDifferential = 0,
                            Probability        = -1
                        };
                    }
                }

                //calc conditions
                bool satisfied = true;
                for (int i = 0; i < CipherThreeConfiguration.SBOXNUM; i++)
                {
                    if (curDiffSBoxes[i].OutputDifferential != outputDiffs[i])
                    {
                        satisfied = false;
                    }
                }

                //check if conditions are satisfied
                if (!satisfied)
                {
                    continue;
                }

                //copy object
                Characteristic characteristic = res.Clone() as Characteristic;

                //calculate inputDifference
                int inputDiff = 0;
                for (int i = CipherThreeConfiguration.SBOXNUM - 1; i >= 0; i--)
                {
                    inputDiff = inputDiff ^ curDiffSBoxes[i].InputDifferential;
                    if ((i - 1) >= 0)
                    {
                        inputDiff = inputDiff << CipherThreeConfiguration.BITWIDTHCIPHERFOUR;
                    }
                }

                //outputDifference for previous round
                int outputDiffPreviousRound = inputDiff;

                //calc new prob
                // ReSharper disable once CompareOfFloatsByEqualityOperator
                if (characteristic != null && characteristic.Probability != -1)
                {
                    for (int i = 0; i < CipherThreeConfiguration.SBOXNUM; i++)
                    {
                        if (curDiffSBoxes[i].Count == 0)
                        {
                            continue;
                        }
                        characteristic.Probability = characteristic.Probability * (curDiffSBoxes[i].Count / 16.0);
                    }
                }
                else
                {
                    double value = 1.0;
                    for (int i = 0; i < CipherThreeConfiguration.SBOXNUM; i++)
                    {
                        if (curDiffSBoxes[i].Count == 0)
                        {
                            continue;
                        }
                        value = value * (curDiffSBoxes[i].Count / 16.0);
                    }

                    if (characteristic != null)
                    {
                        characteristic.Probability = value;
                    }
                }

                //store result
                if (characteristic != null)
                {
                    characteristic.InputDifferentials[round - 1]  = inputDiff;
                    characteristic.OutputDifferentials[round - 1] = outputDiff;

                    //go one round deeper
                    Characteristic retval = FindBestCharacteristic(round - 1, differentialsList,
                                                                   outputDiffPreviousRound, characteristic);

                    //check if there is a result
                    if (retval != null)
                    {
                        diffList.Add(retval);
                    }
                }
            }

            //search for the best result
            Characteristic best = new CipherThreeCharacteristic();

            foreach (var curDiffs in diffList)
            {
                if (best.Probability < curDiffs.Probability)
                {
                    best = curDiffs;
                }
            }

            return(best);
        }