Table of Contents

KeyedDeferredFinalBlockHashAlgorithm Class

Definition

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

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

blockSize int

The fixed size, in bits, of each block consumed by the algorithm. Must be a positive multiple of 8.

maximumKeySize int

The maximum accepted key size, in bits. Must be a positive multiple of 8.

Exceptions

ArgumentOutOfRangeException

blockSize or maximumKeySize is 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

disposing bool

true 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

ProductVersions
.NET8, 10

See Also