public override SymmetricCipherResult ProcessPayload(IModeBlockCipherParameters param) { CheckPayloadRequirements(param.Payload); if (param.Payload.BitLength / _engine.BlockSizeBits < PARTITIONS) { throw new ArgumentException($"CBCI mode needs at least {PARTITIONS} blocks of data"); } var payloads = TdesPartitionHelpers.TriPartitionBitString(param.Payload); var ivs = TdesPartitionHelpers.SetupIvs(param.Iv); var key = param.Key.ToBytes(); var engineParam = new EngineInitParameters(param.Direction, key, param.UseInverseCipherMode); _engine.Init(engineParam); var outBuffer = GetOutputBuffer(param.Payload.BitLength); if (param.Direction == BlockCipherDirections.Encrypt) { Encrypt(param, payloads, ivs, outBuffer); } else { Decrypt(param, payloads, ivs, outBuffer); } return(new SymmetricCipherResult( new BitString(outBuffer).GetMostSignificantBits(param.Payload.BitLength) )); }
private MCTResult <AlgoArrayResponse> Encrypt(IModeBlockCipherParameters param) { if (param.Payload.BitLength != 192) { throw new ArgumentException("Data must be 192 bits"); } var ivs = TdesPartitionHelpers.SetupIvs(param.Iv); var pts = TdesPartitionHelpers.TriPartitionBitString(param.Payload); var responses = new List <AlgoArrayResponse> { new AlgoArrayResponse { IV = ivs[0], Keys = param.Key, PlainText = param.Payload } }; var lastCipherTexts = new List <BitString>(); var indexAtWhichToStartSaving = NUMBER_OF_ITERATIONS - NUMBER_OF_OUTPUTS_TO_SAVE; for (var i = 0; i < NumberOfCases; i++) { for (var j = 0; j < NUMBER_OF_ITERATIONS; j++) { for (var k = 0; k < PARTITIONS; k++) { var result = _algo.ProcessPayload(new ModeBlockCipherParameters( BlockCipherDirections.Encrypt, responses[i].Keys, ivs[k].XOR(pts[k]) )).Result; pts[k] = ivs[k].GetDeepCopy(); ivs[k] = result.GetDeepCopy(); } if (j >= indexAtWhichToStartSaving) { lastCipherTexts.Insert(0, ivs[NUMBER_OF_ITERATIONS - 1 - j].GetDeepCopy()); } } responses.Last().CipherText = ivs[0].ConcatenateBits(ivs[1]).ConcatenateBits(ivs[2]); responses.Add(new AlgoArrayResponse { IV = ivs[0], Keys = _keyMaker.MixKeys(new TDESKeys(responses[i].Keys.GetDeepCopy()), lastCipherTexts.ToList()).ToOddParityBitString(), PlainText = pts[0].ConcatenateBits(pts[1].ConcatenateBits(pts[2])) }); } responses.RemoveAt(responses.Count() - 1); return(new MCTResult <AlgoArrayResponse>(responses)); }
private MCTResult <AlgoArrayResponse> Encrypt(IModeBlockCipherParameters param) { var ivs = TdesPartitionHelpers.SetupIvs(param.Iv); var responses = new List <AlgoArrayResponse> { new AlgoArrayResponse { IV = ivs[0], Keys = param.Key.GetDeepCopy(), PlainText = param.Payload.GetDeepCopy() } }; var lastCipherTexts = new List <BitString>(); var indexAtWhichToStartSaving = NUMBER_OF_ITERATIONS - NUMBER_OF_OUTPUTS_TO_SAVE; for (var i = 0; i < NumberOfCases; i++) { var encryptionOutputs = new List <BitString>(); var cipherText = new BitString(0); var encryptionInput = new BitString(0); var key = responses.Last().Keys.GetDeepCopy(); for (var j = 0; j < NUMBER_OF_ITERATIONS; j++) { encryptionInput = j < PARTITIONS ? ivs[j] : encryptionOutputs[j - PARTITIONS]; var encryptionOutput = _algo.ProcessPayload(new ModeBlockCipherParameters( BlockCipherDirections.Encrypt, key, encryptionInput )).Result; encryptionOutputs.Add(encryptionOutput.GetDeepCopy()); cipherText = param.Payload.XOR(encryptionOutput); if (j >= indexAtWhichToStartSaving) { lastCipherTexts.Insert(0, cipherText.GetDeepCopy()); } param.Payload = encryptionInput.GetDeepCopy(); } responses.Last().CipherText = cipherText.GetDeepCopy(); ivs = TdesPartitionHelpers.SetupIvs(encryptionOutputs[9995].XOR(cipherText)); responses.Add(new AlgoArrayResponse { IV = ivs[0], Keys = _keyMaker.MixKeys(new TDESKeys(responses[i].Keys.GetDeepCopy()), lastCipherTexts.ToList()).ToOddParityBitString(), PlainText = responses.Last().PlainText.XOR(encryptionInput) }); } responses.RemoveAt(responses.Count() - 1); return(new MCTResult <AlgoArrayResponse>(responses)); }
public MCTResult <AlgoArrayResponse> Encrypt(IModeBlockCipherParameters param) { var ivs = TdesPartitionHelpers.SetupIvs(param.Iv); var responses = new List <AlgoArrayResponse> { new AlgoArrayResponse { IV = ivs[0], Keys = param.Key, PlainText = param.Payload } }; var numberOfOutputsToSave = 192 / Shift; var indexAtWhichToStartSaving = NUMBER_OF_ITERATIONS - numberOfOutputsToSave; for (var i = 0; i < NumberOfCases; i++) { ivs = TdesPartitionHelpers.SetupIvs(responses[i].IV.GetDeepCopy()); var tempText = responses[i].PlainText.GetDeepCopy(); BitString prevTempIv = null; var tempIv = responses[i].IV.GetDeepCopy(); var keysForThisRound = responses[i].Keys; BitString output = null; var holdouts = new BitString[3]; var lastCipherTexts = new List <BitString>(); for (var j = 0; j < NUMBER_OF_ITERATIONS; j++) { switch (j) { case 0: tempIv = ivs[0].GetDeepCopy(); break; case 1: tempIv = ivs[1].GetDeepCopy(); break; case 2: tempIv = ivs[2].GetDeepCopy(); break; default: tempIv = prevTempIv.MSBSubstring(Shift, 64 - Shift).ConcatenateBits(holdouts[2]); break; } prevTempIv = tempIv.GetDeepCopy(); output = _algo.ProcessPayload(new ModeBlockCipherParameters( BlockCipherDirections.Encrypt, tempIv, keysForThisRound, tempText) ).Result; holdouts[2] = holdouts[1]; holdouts[1] = holdouts[0]; holdouts[0] = output; tempText = prevTempIv.MSBSubstring(0, Shift); if (j >= indexAtWhichToStartSaving) { lastCipherTexts.Insert(0, output.GetDeepCopy()); } } responses[i].CipherText = output; var newIv = prevTempIv.MSBSubstring(Shift, 64 - Shift).ConcatenateBits(output); var newIvs = TdesPartitionHelpers.SetupIvs(newIv); responses.Add(new AlgoArrayResponse() { Keys = _keyMaker.MixKeys(new TDESKeys(responses[i].Keys.GetDeepCopy()), lastCipherTexts.ToList()) .ToOddParityBitString(), PlainText = prevTempIv.GetDeepCopy().MSBSubstring(0, Shift), IV = newIvs[0] }); } responses.RemoveAt(responses.Count - 1); return(new MCTResult <AlgoArrayResponse>(responses)); }