KeyedDeferredFinalBlockHashAlgorithm Class
Definition
- Namespace
- Bodu.Security.Cryptography
- Assembly
- Bodu.Security.Cryptography.dll
- Package
- Bodu.Security.Cryptography 1.2.0
Represents the abstract base class for hash algorithms that support an optional secret key and defer compression of the final block until HashFinal() is called, following the BLAKE-family deferred-finalization pattern.
public abstract class KeyedDeferredFinalBlockHashAlgorithm : DeferredFinalBlockHashAlgorithm, ICryptoTransform, IDisposable
- Inheritance
-
KeyedDeferredFinalBlockHashAlgorithm
- Implements
- Derived
- Inherited Members
- Extension Methods
Examples
// BLAKE2b in keyed MAC mode - the key is optional and may be up to MaximumKeySize bits.
byte[] key = new byte[32];
RandomNumberGenerator.Fill(key);
using var mac = new Blake2b { Key = key };
byte[] tag = mac.ComputeHash("message"u8.ToArray());
// Or use the same type unkeyed for a plain BLAKE2b digest.
using var digest = new Blake2b();
byte[] hash = digest.ComputeHash("message"u8.ToArray());
Remarks
This class extends DeferredFinalBlockHashAlgorithm with optional key-handling logic shared by keyed BLAKE-family hashes such as Blake2b and Blake2s. It centralizes defensive copying, key-length validation, secure disposal of secret material, and the sealed Initialize() override that orchestrates hash-state reset followed by key-block injection when a key is set.
The key is optional: assigning an empty array (or never assigning a key) places the instance in the standard unkeyed digest mode. Assigning a non-empty array of at most MaximumKeySize / 8 bytes switches the instance to the keyed MAC mode defined in RFC 7693 Section 2.8 - the key is zero-padded to the block size and prepended as the first message block.
Derived classes must implement InitializeHashState() to restore their algorithm-specific chaining variables and encode the key length into the parameter block, and ProcessBlock(ReadOnlySpan<byte>, ulong, bool) / ProcessFinalBlock() as required by the grandparent.
When to derive from this class. Pick KeyedDeferredFinalBlockHashAlgorithm for BLAKE-family hashes that accept an optional, variable-length key per RFC 7693 §2.8 - the canonical users are Blake2b and Blake2s. For BLAKE-family hashes without a key (e.g. Blake3 ) derive from DeferredFinalBlockHashAlgorithm. For Merkle-Damgård keyed hashes with a fixed-length key (Poly1305, SipHash) derive from KeyedBlockHashAlgorithm.
Constructors
KeyedDeferredFinalBlockHashAlgorithm(int, int)
Initializes a new instance of the KeyedDeferredFinalBlockHashAlgorithm class with the specified input block size and maximum key size.
protected KeyedDeferredFinalBlockHashAlgorithm(int blockSize, int maximumKeySize)
Parameters
blockSizeintThe fixed size, in bits, of each block consumed by the algorithm. Must be a positive multiple of 8.
maximumKeySizeintThe maximum accepted key size, in bits. Must be a positive multiple of 8.
Exceptions
- ArgumentOutOfRangeException
blockSizeormaximumKeySizeis less than or equal to zero.
Fields
KeyValue
Internal storage for the optional secret key. null when the instance operates in the unkeyed digest profile; otherwise a defensive copy of the caller-supplied key. Always assigned via defensive copy and cleared on disposal.
protected byte[]? KeyValue
Field Value
- byte[]
Properties
Key
Gets or sets the optional secret key used to compute a keyed MAC digest.
public byte[] Key { get; set; }
Property Value
- byte[]
A byte array of 1 to MaximumKeySize / 8 bytes that enables keyed MAC mode, or an empty array when operating in the unkeyed digest profile. Both the getter and the setter operate on defensive copies.
Remarks
When the key is non-empty, the instance operates in the keyed MAC mode defined in RFC 7693 Section 2.8. The key length is encoded into the parameter block by InitializeHashState(), and the key itself (zero-padded to the block size) is prepended as the first message block before any caller-supplied input is processed.
Setting the key calls Initialize() so that the algorithm state is immediately rebuilt for the new key. Setting an empty array clears the key and reverts the instance to unkeyed digest mode.
The property may only be changed before hashing has begun; once TransformBlock(byte[], int, int, byte[], int) or a
ComputeHash overload has been called, the value is immutable until
Initialize() is called.
Exceptions
- ArgumentNullException
The assigned value is null.
- CryptographicException
The assigned key is longer than MaximumKeySize / 8 bytes.
- ObjectDisposedException
The algorithm instance has been disposed.
- CryptographicUnexpectedOperationException
A hash computation is already in progress.
MaximumKeySize
Gets the maximum accepted key size, in bits, for this algorithm instance. Divide by 8 to obtain the equivalent byte length used when allocating or validating Key.
public int MaximumKeySize { get; }
Property Value
- int
The maximum number of bits accepted as a secret key.
Exceptions
- ObjectDisposedException
The algorithm instance has been disposed.
Methods
Dispose(bool)
Releases the resources used by the algorithm and zeros the residual buffer.
protected override void Dispose(bool disposing)
Parameters
disposingbooltrue to release both managed and unmanaged resources; false to release only unmanaged resources.
Remarks
The dispose latch ensures that subsequent calls are no-ops and that the residual buffer is cleared at most once.
Derived classes that hold algorithm-specific state, buffers, keys, or other secret material should override
Dispose(bool), clear their own state when disposing is
true, and then call the base implementation.
Initialize()
Resets the algorithm to its initial state. Clears the inherited residual buffer and counters via
base.Initialize(), then rebuilds the algorithm-specific hash state through
InitializeHashState() and, when a key has been set, injects the key block as the first message
block. Sealed so that the key-injection protocol cannot be accidentally bypassed by derived classes.
public override sealed void Initialize()
Exceptions
- ObjectDisposedException
The instance has been disposed.
InitializeHashState()
Resets the algorithm-specific chaining variables to their initialization values and encodes any configuration parameters (such as digest length and key length) into the parameter block. Called by the sealed Initialize() before key-block injection.
protected abstract void InitializeHashState()
Remarks
Implementations should read KeyValue to determine the key length (kk) for parameter-block
encoding, as KeyValue is already updated to the new value before Initialize() runs.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |