Table of Contents

CtsModeTransform Class

Definition

Namespace
Bodu.Security.Cryptography
Assembly
Bodu.Security.Cryptography.dll
Package
Bodu.Security.Cryptography 1.2.0
Source
CtsModeTransform.cs

Applies Ciphertext Stealing (CTS) over CBC mode to an underlying IBlockCipher, allowing encryption of inputs whose length is not a multiple of the block size without requiring padding.

public sealed class CtsModeTransform : IBlockCipherModeTransform, IDisposable
Inheritance
CtsModeTransform
Implements
Inherited Members
Extension Methods

Examples

using System.Security.Cryptography;
using Bodu.Security.Cryptography;

// Most callers should set SymmetricAlgorithm.Mode = CipherBlockMode.CTS instead of using this directly.
using IBlockCipher cipher = new AesBlockCipher(key);
byte[] iv = RandomNumberGenerator.GetBytes(cipher.BlockSize / 8);
IBlockCipherModeTransform cts = new CtsModeTransform(cipher, iv);

// CTS preserves length: plaintext.Length == ciphertext.Length, no padding required.
byte[] ciphertext = new byte[plaintext.Length];
int written = cts.Transform(plaintext, ciphertext, encrypt: true);

Remarks

CTS produces ciphertext of exactly the same length as the plaintext by "stealing" bytes from the penultimate ciphertext block to complete the final partial block. For block-aligned inputs (where the total length is a multiple of the block size), CTS behaves identically to CBC with no stealing.

The CTS steal algorithm (CS3 / IEEE 1619 variant):

  • All complete blocks except the last two are processed normally in CBC mode.
  • Encrypt: the penultimate block is CBC-encrypted to E; the final partial block P_n is zero-padded and CBC-chained against E (that is, (P_n || 0) XOR E is encrypted) to produce C_n (full block); C_{n-1} = E[0:m]. Output: C_n then C_{n-1}.
  • Decrypt: C_n is decrypted to recover (P_n XOR E[0:m]) || E[m:]; E is reconstructed from the truncated C_{n-1} and the recovered high bytes; P_n is obtained by XORing off E[0:m]; then the full E is CBC-decrypted to P_{n-1}.

The input to Transform(ReadOnlySpan<byte>, Span<byte>, bool) must be at least one full block long. For inputs of exactly one block, the result is identical to standard CBC encryption or decryption.

When to use CTS. Pick CTS when ciphertext length must equal plaintext length and the input is not block-aligned - typical in fixed-size record formats, network frames with strict size budgets, and on-disk layouts where adding padding bytes is impossible. CTS shares CBC's lack of authentication and its sequential nature; for new general-purpose encryption an AEAD mode (GcmModeTransform, EaxModeTransform) is preferable. The variant implemented here is CS3 / IEEE 1619 (the order used by NIST SP 800-38A Addendum and most modern interop).

Constructors

CtsModeTransform(IBlockCipher, byte[])

Initializes a new instance of the CtsModeTransform class.

public CtsModeTransform(IBlockCipher cipher, byte[] iv)

Parameters

cipher IBlockCipher

The underlying block cipher.

iv byte[]

The initialization vector for the CBC chain. Must equal the cipher block size. A defensive copy is taken; the caller's array is not modified.

Exceptions

ArgumentNullException

cipher or iv is null.

ArgumentException

iv length does not equal the cipher block size.

Methods

Dispose()

Releases the resources used by this instance and zeroes the seed and running CBC chaining vector so that key-equivalent state does not linger in memory after disposal. The underlying IBlockCipher is not disposed by this type - ownership remains with the caller.

public void Dispose()

Remarks

Idempotent.

Transform(ReadOnlySpan<byte>, Span<byte>, bool)

Transforms input under the mode's chaining strategy and writes the result to output.

public int Transform(ReadOnlySpan<byte> input, Span<byte> output, bool encrypt)

Parameters

input ReadOnlySpan<byte>

The input data to transform. Its length must be a positive multiple of the underlying cipher block size.

output Span<byte>

The destination span. Its length must be greater than or equal to the length of input.

encrypt bool

true to encrypt the input; false to decrypt.

Returns

int

The number of bytes written to output.

Exceptions

ArgumentException

Thrown when input's length is not a multiple of the block size or when output is too small.

Applies to

ProductVersions
.NET8, 10