Example #1
0
        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));
        }