Table of Contents

KeyedBlockHashAlgorithm Class

Definition

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

Represents the abstract base class for hash algorithms that require a secret key and process data in fixed-size blocks.

public abstract class KeyedBlockHashAlgorithm : BlockHashAlgorithm, ICryptoTransform, IDisposable
Inheritance
KeyedBlockHashAlgorithm
Implements
Derived
Inherited Members
Extension Methods

Examples

// Consume through a concrete keyed derivative - Poly1305 needs a 32-byte one-time key.
byte[] key = new byte[32];
RandomNumberGenerator.Fill(key);

using var mac = new Poly1305 { Key = key };
byte[] tag = mac.ComputeHash("message"u8.ToArray());

// SipHash takes a 16-byte key and is the standard hash-table keyed primitive.
byte[] sipKey = new byte[16];
RandomNumberGenerator.Fill(sipKey);

using var siphash = new SipHash64 { Key = sipKey };
byte[] fingerprint = siphash.ComputeHash("hello"u8.ToArray());

Remarks

This class extends BlockHashAlgorithm with key-handling logic shared by keyed block hashes such as Poly1305 and SipHash. It centralizes defensive copying, key-length validation, disposal of secret material, and the hook (OnKeyChanged()) used by derived classes to derive any key-dependent schedule or internal state.

Derived classes supply the required key length via the KeyedBlockHashAlgorithm(int, int) constructor. The Key property setter validates the supplied byte array against that length, stores a defensive copy in KeyValue, and then invokes OnKeyChanged() so the derived algorithm can rebuild any key-dependent state.

When to derive from this class. Pick KeyedBlockHashAlgorithm for keyed hashes that follow the Merkle-Damgård pad-and-finalize pattern and require a fixed-length key - Poly1305 (32-byte key) and SipHash (16-byte key) are the canonical users. For BLAKE-family hashes that accept an optional variable-length key derive from KeyedDeferredFinalBlockHashAlgorithm instead. For unkeyed Merkle-Damgård hashes use BlockHashAlgorithm directly.

Constructors

KeyedBlockHashAlgorithm(int, int)

Initializes a new instance of the KeyedBlockHashAlgorithm class with the specified input block size and required key size.

protected KeyedBlockHashAlgorithm(int blockSize, int keySize)

Parameters

blockSize int

The fixed size of input blocks, in bits, that the algorithm processes. Must be a positive multiple of 8. This must match the internal block size used by the underlying hash structure.

keySize int

The exact required key size, in bits, that the derived algorithm accepts. Must be a positive multiple of 8. Used by the Key setter (after dividing by 8) to validate caller-supplied key material.

Exceptions

ArgumentOutOfRangeException

blockSize or keySize is less than or equal to zero.

Fields

KeySizeValue

Holds the required key size, in bits, that the derived algorithm accepts. Supplied via the constructor; aligns with the BCL convention used by KeySize. Divide by 8 to obtain the equivalent byte length used when validating Key.

protected readonly int KeySizeValue

Field Value

int

KeyValue

Internal storage for the key used by the algorithm. Always assigned via defensive copy and cleared on disposal.

protected byte[]? KeyValue

Field Value

byte[]

Remarks

Declared byte[] nullable to honestly reflect that the field can be observed in three states: null on a freshly-constructed instance whose constructor has not yet seeded a key, after Dispose(bool) has cleared it, and between assignments. The Key getter and Initialize() validation both treat a null value as a contract violation and throw a CryptographicException.

Properties

Key

Gets or sets the secret key used by the keyed hash algorithm to compute the message authentication code (MAC).

public virtual byte[] Key { get; set; }

Property Value

byte[]

A byte array containing the key material. Both the getter and the setter operate on defensive copies.

Remarks

The key must be set prior to calling any hashing methods such as ComputeHash(byte[]). The setter stores a private copy of the supplied array, then invokes OnKeyChanged() so derived classes can rebuild any key-dependent internal state (for example, a polynomial key schedule or pre-computed state vectors).

The getter returns a defensive copy of the stored key so external callers cannot mutate the internal representation.

Exceptions

ObjectDisposedException

The algorithm instance has been disposed.

CryptographicUnexpectedOperationException

A hash computation has already started, and the key may not be reassigned while the algorithm is in use.

ArgumentNullException

The assigned value is null.

CryptographicException

The length of the assigned key does not match the required key size for this algorithm.

Methods

Dispose(bool)

Releases the unmanaged resources used by the algorithm and clears the key from memory.

protected override void Dispose(bool disposing)

Parameters

disposing bool

true to release both managed and unmanaged resources; false to release only unmanaged resources.

Remarks

Ensures all internal secrets are overwritten with zeros before releasing resources.

Initialize()

Resets the algorithm to its initial state, ready to accept fresh input. Derived classes should override OnKeyChanged() - invoked automatically from here - to rebuild any key-dependent internal state.

public override void Initialize()

Exceptions

ObjectDisposedException

The algorithm instance has been disposed.

CryptographicException

No key has been assigned, or the currently assigned key is not of the required length.

OnKeyChanged()

Called after KeyValue has been assigned or the algorithm has been re-initialized. Derived classes override this to rebuild any key-dependent internal state such as a round-key schedule, precomputed vectors, or accumulator reset.

protected virtual void OnKeyChanged()

Remarks

By contract, when this method runs KeyValue is guaranteed to be non-null and of byte length KeySizeValue / 8. It is invoked from the Key setter, from Initialize(), and should be invoked by derived constructors after they have placed a default key into KeyValue.

The default implementation is a no-op so that derived classes with no key-dependent precomputation pay no overhead.

Applies to

ProductVersions
.NET8, 10

See Also