public int PartialDecrypt(DifferentialKeyRecoveryAttack attack, int block) { CipherThreeDifferentialKeyRecoveryAttack cipherThreeAttack = attack as CipherThreeDifferentialKeyRecoveryAttack; int result = block; if (cipherThreeAttack != null && cipherThreeAttack.RecoveredSubkey3) { result = DecryptSingleRound(result, cipherThreeAttack.Subkey3, false, true); } if (cipherThreeAttack != null && cipherThreeAttack.RecoveredSubkey2) { result = DecryptSingleRound(result, cipherThreeAttack.Subkey2, true, false); } if (cipherThreeAttack != null && cipherThreeAttack.RecoveredSubkey1) { result = DecryptSingleRound(result, cipherThreeAttack.Subkey1, false, false); } return(result); }
public DifferentialAttackRoundConfiguration RefreshPairLists(DifferentialAttackRoundConfiguration roundConfig, List <Differential> diffListOfSBox, DifferentialKeyRecoveryAttack attack, IEncryption encryption) { throw new NotImplementedException(); }
public DifferentialAttackLastRoundResult AttackFirstRound(DifferentialKeyRecoveryAttack attack, IEncryption encryption) { throw new NotImplementedException(); }
public DifferentialAttackRoundConfiguration GenerateConfigurationAttack(int round, bool[] sBoxesToAttack, AbortingPolicy abortingPolicy, SearchPolicy searchPolicy, List <Differential> diffListOfSBox, DifferentialKeyRecoveryAttack attack, IEncryption encryption) { if (round <= 1) { throw new ArgumentException("To attack round 1, use AttackFirstRound()"); } else if (sBoxesToAttack == null) { throw new ArgumentException("At least one SBox must be specified to attack"); } DifferentialAttackRoundConfiguration result = new DifferentialAttackRoundConfiguration { ActiveSBoxes = sBoxesToAttack, Round = round, AbortingPolicy = abortingPolicy, SearchPolicy = searchPolicy }; int inputDifference = -1; int expectedDifference = -1; double probabilityAccumulated = 0.0; List <Characteristic> bestCharacteristics = null; if (result.Round == 3) { result.IsLast = true; } else if (result.Round == 2) { result.IsBeforeLast = true; } List <Characteristic> characteristics = FindBestCharacteristicsDepthSearch(result, diffListOfSBox); //Delete Characteristics which are not usable List <Characteristic> toDelete = new List <Characteristic>(); foreach (var curCharacteristic in characteristics) { bool[] conditionArray = new bool[CipherThreeConfiguration.SBOXNUM]; for (int i = 0; i < CipherThreeConfiguration.SBOXNUM; i++) { conditionArray[i] = true; if (sBoxesToAttack[i]) { if (GetSubBlockFromBlock(curCharacteristic.InputDifferentials[round - 1], i) == 0) { conditionArray[i] = false; } } } for (int i = 0; i < CipherThreeConfiguration.SBOXNUM; i++) { if (conditionArray[i] == false) { toDelete.Add(curCharacteristic); } } } //delete unusable characteristics foreach (var characteristicToDelete in toDelete) { characteristics.Remove(characteristicToDelete); } foreach (var characteristic in characteristics) //Parallel.ForEach(characteristics, (characteristic) => { List <Characteristic> differentialList = FindSpecifiedDifferentialDepthSearch(characteristic.InputDifferentials[0], characteristic.InputDifferentials[round - 1], round, diffListOfSBox); if (differentialList.Count == 0) { //return; continue; } double testProbability = 0.0; foreach (var curCharacteristic in differentialList) { testProbability += curCharacteristic.Probability; } _semaphoreSlim.Wait(); try { if (testProbability > probabilityAccumulated) { probabilityAccumulated = testProbability; bestCharacteristics = differentialList; Console.WriteLine("Current best: InputDiff: " + bestCharacteristics[0].InputDifferentials[0] + " ExpectedDiff: " + bestCharacteristics[0].InputDifferentials[2] + " Probability: " + probabilityAccumulated); } } finally { _semaphoreSlim.Release(); } }//); inputDifference = bestCharacteristics[0].InputDifferentials[0]; expectedDifference = bestCharacteristics[0].InputDifferentials[round - 1]; result.InputDifference = inputDifference; result.ExpectedDifference = expectedDifference; result.Characteristics = bestCharacteristics; //result.Characteristics = new List<Characteristic>(); //result.Characteristics.Add(bestCharacteristics[0]); result.Probability = probabilityAccumulated; int pairCount = 16; result.UnfilteredPairList = GenerateInputPairList(inputDifference, pairCount); //result.FilteredPairList = FilterPairs(result, diffListOfSBox, attack, encryption, expectedDifference); result.FilteredPairList = result.UnfilteredPairList; #if DEBUG Console.WriteLine("Generated " + result.UnfilteredPairList.Count + " pairs and there stayed " + result.FilteredPairList.Count + " filtered pairs"); #endif return(result); }
public DifferentialAttackRoundResult RecoverKeyInformation(DifferentialKeyRecoveryAttack attack, DifferentialAttackRoundConfiguration configuration, IEncryption encryption) { if (configuration.ActiveSBoxes == null) { throw new ArgumentException("activeSBoxes should contain at least one active SBox"); } DifferentialAttackRoundResult roundResult = new DifferentialAttackRoundResult(); //Generate border for the loop int loopBorder = CalculateLoopBorder(configuration.ActiveSBoxes); for (int i = 0; i < loopBorder; i++) //Parallel.For(0, loopBorder, i => { int guessedKey = GenerateValue(configuration.ActiveSBoxes, i); KeyProbability curTry = new KeyProbability() { Counter = 0, Key = guessedKey }; foreach (var curPair in configuration.FilteredPairList) { Pair encryptedPair = new Pair() { LeftMember = encryption.EncryptBlock(curPair.LeftMember), RightMember = encryption.EncryptBlock(curPair.RightMember) }; //reverse round with the guessed key int leftMemberSingleDecrypted = ReverseSBoxBlock(encryptedPair.LeftMember ^ curTry.Key); int rightMemberSingleDecrypted = ReverseSBoxBlock(encryptedPair.RightMember ^ curTry.Key); int differentialToCompare = (leftMemberSingleDecrypted ^ rightMemberSingleDecrypted); if (differentialToCompare == configuration.ExpectedDifference) { curTry.Counter++; } } //synchronize access to resultList _semaphoreSlim.Wait(); try { roundResult.KeyCandidateProbabilities.Add(curTry); } finally { _semaphoreSlim.Release(); } }//); //sort by counter KeyProbability bestPossibleKey = new KeyProbability() { Counter = 0, Key = 0 }; foreach (var curKey in roundResult.KeyCandidateProbabilities) { if (curKey.Counter > bestPossibleKey.Counter) { bestPossibleKey = curKey; } } roundResult.PossibleKey = bestPossibleKey.Key; roundResult.Probability = bestPossibleKey.Counter / (double)configuration.UnfilteredPairList.Count; roundResult.ExpectedProbability = configuration.Probability; roundResult.KeyCandidateProbabilities = roundResult.KeyCandidateProbabilities.OrderByDescending(item => item.Counter).ToList(); #if DEBUG Console.WriteLine("Expected probability: {0:N4}" + " Expected count: " + (configuration.Probability * configuration.UnfilteredPairList.Count), configuration.Probability); foreach (var curKeyProbability in roundResult.KeyCandidateProbabilities)//.GetRange(0,3)) { Console.WriteLine("Guessed key: " + curKeyProbability.Key + " Count: " + curKeyProbability.Counter + " Probability: {0:N4}", ((curKeyProbability.Counter / (double)configuration.UnfilteredPairList.Count))); } #endif return(roundResult); }
public List <Pair> FilterPairs(DifferentialAttackRoundConfiguration roundConfig, List <Differential> diffListOfSBox, DifferentialKeyRecoveryAttack attack, IEncryption encryption, int expectedDifferential) { //cast to use the object CipherThreeDifferentialKeyRecoveryAttack cipherFourAttack = attack as CipherThreeDifferentialKeyRecoveryAttack; if (cipherFourAttack == null) { throw new ArgumentNullException(nameof(attack)); } //contains the filtered pairs List <Pair> resultList = new List <Pair>(); List <int>[] arrayOfPossibleDifferentialsForSBoxes = new List <int> [CipherThreeConfiguration.SBOXNUM]; int[] arrayOfExpectedInputDifferentialsForSBoxes = new int[CipherThreeConfiguration.SBOXNUM]; for (int i = 0; i < CipherThreeConfiguration.SBOXNUM; i++) { arrayOfPossibleDifferentialsForSBoxes[i] = new List <int>(); arrayOfExpectedInputDifferentialsForSBoxes[i] = expectedDifferential; if (arrayOfExpectedInputDifferentialsForSBoxes[i] == 0) { arrayOfPossibleDifferentialsForSBoxes[i].Add(0); } } //iterate over the differentials foreach (var curDiff in diffListOfSBox) { //Skip 0 InputDiff / OutputDiff if (curDiff.InputDifferential == 0) { continue; } for (int i = 0; i < CipherThreeConfiguration.SBOXNUM; i++) { if (arrayOfExpectedInputDifferentialsForSBoxes[i] == curDiff.InputDifferential) { arrayOfPossibleDifferentialsForSBoxes[i].Add(curDiff.OutputDifferential); } } } //check all pairs for the conditions foreach (var curPair in roundConfig.UnfilteredPairList) { int cipherTextLeftMember = encryption.EncryptBlock(curPair.LeftMember); int cipherTextRightMember = encryption.EncryptBlock(curPair.RightMember); cipherTextLeftMember = PartialDecrypt(attack, cipherTextLeftMember); cipherTextRightMember = PartialDecrypt(attack, cipherTextRightMember); int diffOfCipherText = (cipherTextLeftMember ^ cipherTextRightMember); int[] diffOfCipherTextSBoxes = new int[CipherThreeConfiguration.SBOXNUM]; bool[] conditionsOfSBoxes = new bool[CipherThreeConfiguration.SBOXNUM]; for (int i = 0; i < CipherThreeConfiguration.SBOXNUM; i++) { diffOfCipherTextSBoxes[i] = diffOfCipherText; conditionsOfSBoxes[i] = false; } for (int i = 0; i < CipherThreeConfiguration.SBOXNUM; i++) { foreach (var possibleOutputDiff in arrayOfPossibleDifferentialsForSBoxes[i]) { if (possibleOutputDiff == diffOfCipherTextSBoxes[i]) { conditionsOfSBoxes[i] = true; } } } bool satisfied = true; for (int i = 0; i < CipherThreeConfiguration.SBOXNUM; i++) { if (conditionsOfSBoxes[i] == false) { satisfied = false; } } if (satisfied) { resultList.Add(curPair); } } return(resultList); }