public List <Characteristic> FindSpecifiedDifferentialDepthSearch(int inputDiff, int outputDiff, int round, List <Differential> differentialNumList) { //Decrement round round--; //Starting object Characteristic inputObj = new CipherThreeCharacteristic(); //calculate previous difference int outputDiffPreviousRound = (outputDiff); //start depth-first search List <Characteristic> retVal = FindAllCharacteristics(round, differentialNumList, outputDiffPreviousRound, inputObj); // ReSharper disable once CompareOfFloatsByEqualityOperator retVal.RemoveAll(item => ((item.Probability == -1.0) || (item.InputDifferentials[0] != inputDiff))); foreach (var curItem in retVal) { curItem.InputDifferentials[round] = outputDiff; } #if DEBUG //Console.WriteLine("Found " + retVal.Count + " paths with inputDifference = " + inputDiff + " and outputDifference = " + outputDiff); #endif return(retVal); }
public List <Characteristic> FindBestCharacteristicsDepthSearch(DifferentialAttackRoundConfiguration roundConfiguration, List <Differential> differentialsList) { int round = roundConfiguration.Round; //Decrement round for recursive call round--; //result list List <Characteristic> resultList = new List <Characteristic>(); //calculate loop border int loopBorder = CalculateLoopBorder(roundConfiguration.ActiveSBoxes); for (int i = 1; i < loopBorder; i++) //Parallel.For(1, loopBorder, i => { Characteristic inputObj = new CipherThreeCharacteristic(); //expected difference int expectedDifference = GenerateValue(roundConfiguration.ActiveSBoxes, i); int outputDifferencePreviousRound = expectedDifference; inputObj.InputDifferentials[round] = expectedDifference; //start depth-first search Characteristic retVal = FindBestCharacteristic(round, differentialsList, outputDifferencePreviousRound, inputObj); // ReSharper disable once CompareOfFloatsByEqualityOperator if (retVal.Probability != -1) { _semaphoreSlim.Wait(); try { #if DEBUG //Console.WriteLine("Case " + roundConfiguration.GetActiveSBoxes() + " finished iteration i = " + i + " / " + loopBorder); //Console.WriteLine(retVal.ToString()); #endif resultList.Add(retVal); } finally { _semaphoreSlim.Release(); } } }//); var sorted = resultList.OrderByDescending(elem => elem.Probability).ToList(); #if DEBUG foreach (var curRetVAl in sorted) { //Console.WriteLine(curRetVAl.ToString()); } #endif return(sorted); }
public override object Clone() { Characteristic obj = new CipherThreeCharacteristic { InputDifferentials = (int[])this.InputDifferentials.Clone(), OutputDifferentials = (int[])this.OutputDifferentials.Clone(), Probability = this.Probability }; return(obj); }
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); }