public byte[] HandleFinalFullPayloadBlockDecryption(BitString payload, IBlockCipherEngine engine, int numberOfBlocks, int originalPayloadBitLength) { // Decrypt the last full payload block (when there is more than one block) if (numberOfBlocks > 1) { var originalPayloadPaddedToBlockSize = payload.PadToModulus(engine.BlockSizeBits).ToBytes(); // Decrypt the last full payload block (in this case the second to last block) var secondToLastBlock = new byte[engine.BlockSizeBytes]; var secondToLastBlockStartIndex = (numberOfBlocks - 2) * engine.BlockSizeBytes; Array.Copy(originalPayloadPaddedToBlockSize, secondToLastBlockStartIndex, secondToLastBlock, 0, engine.BlockSizeBytes); var decryptedSecondToLastBlockBuffer = new byte[engine.BlockSizeBytes]; engine.ProcessSingleBlock(secondToLastBlock, decryptedSecondToLastBlockBuffer, 0); var decryptedBlock = new BitString(decryptedSecondToLastBlockBuffer); // Pad the payload to the nearest multiple of the block size using the last B−M bits of block cipher decryption of the second-to-last ciphertext block. var amountToPad = (engine.BlockSizeBits - payload.BitLength % engine.BlockSizeBits); if (amountToPad > 0) { payload = payload.ConcatenateBits(BitString.Substring(decryptedBlock, 0, amountToPad)); } var payloadBytes = payload.ToBytes(); TransformText(payloadBytes, engine, numberOfBlocks, originalPayloadBitLength); payload = new BitString(payloadBytes); return(payload.ToBytes()); } return(payload.ToBytes()); }
public byte[] HandleFinalFullPayloadBlockDecryption(BitString payload, IBlockCipherEngine engine, int numberOfBlocks, int originalPayloadBitLength) { // When payload is not a multiple of the block size if (numberOfBlocks > 1 && payload.BitLength % engine.BlockSizeBits != 0) { var numberOfBitsToAdd = engine.BlockSizeBits - payload.BitLength % engine.BlockSizeBits; // Decrypt the last full payload block (in this case the last block) var decryptedLastBlockBuffer = new byte[engine.BlockSizeBytes]; var lastBlock = payload.GetLeastSignificantBits(engine.BlockSizeBits).ToBytes(); engine.ProcessSingleBlock(lastBlock, decryptedLastBlockBuffer, 0); var paddedPayload = payload // The original payload minus the final full block .GetMostSignificantBits(payload.BitLength - engine.BlockSizeBits) // Add the least significant bits of the decrypted last block to pad to a multiple of the block size .ConcatenateBits(new BitString(decryptedLastBlockBuffer).GetLeastSignificantBits(numberOfBitsToAdd)) // Add the last block back onto the payload .ConcatenateBits(payload.GetLeastSignificantBits(engine.BlockSizeBits)); return(paddedPayload.ToBytes()); } return(payload.ToBytes()); }