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));
        }
Beispiel #4
0
        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));
        }