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 Eis 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
cipherIBlockCipherThe underlying block cipher.
ivbyte[]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
cipherorivis null.- ArgumentException
ivlength 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
inputReadOnlySpan<byte>The input data to transform. Its length must be a positive multiple of the underlying cipher block size.
outputSpan<byte>The destination span. Its length must be greater than or equal to the length of
input.encryptbool
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 whenoutputis too small.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |