Shake Class
Definition
- Namespace
- Bodu.Security.Cryptography
- Assembly
- Bodu.Security.Cryptography.dll
- Package
- Bodu.Security.Cryptography 1.2.0
- Source
- Shake.cs
Computes a hash using the SHAKE family of extendable output functions (XOFs) as defined in NIST FIPS 202.
Supports security levels of 128 and 256 bits with a configurable output size. This class cannot be inherited.
public sealed class Shake : BufferedBlockHashAlgorithm, ICryptoTransform, IDisposable
- Inheritance
-
Shake
- Implements
- Inherited Members
- Extension Methods
Examples
// SHAKE128 producing 256-bit output.
using var shake = new Shake(256, 128);
byte[] digest = shake.ComputeHash(Encoding.UTF8.GetBytes("hello"));
// SHAKE256 producing 512-bit output.
using var shake256 = new Shake(512, 256);
byte[] longer = shake256.ComputeHash(message);
Remarks
Shake is built on the same Keccak-f[1600] permutation as SHA-3, operating over a
1600-bit (200-byte) state. The two SHAKE variants differ only in their rate and, therefore, their security margin:
- SHAKE128: rate = 168 bytes, capacity = 32 bytes, security level = 128 bits.
- SHAKE256: rate = 136 bytes, capacity = 64 bytes, security level = 256 bits.
Unlike the fixed-length SHA-3 variants, SHAKE is an XOF - the output length is independent of the security parameter
and may be any positive multiple of 8 bits. The domain separation byte 0x1F distinguishes SHAKE from SHA-3 (
0x06) and from raw Keccak. Multi-rate padding (pad10*1) appends the domain byte, zero or more zero bytes, and
a 0x80 byte at the last position of the final rate block.
When used via HashAlgorithm, HashSizeValue holds the desired output length in bits and
securityLevel selects the SHAKE variant. ComputeHash(byte[]) therefore produces
exactly outputBits / 8 bytes regardless of which security level is chosen.
Parameters at a glance.
- State: 1600 bits (200 bytes); Keccak-f[1600] permutation.
- Output size: configurable, any positive multiple of 8 bits.
- Security level: 128 (SHAKE128) or 256 (SHAKE256).
- Domain separation:
0x1F; multi-rate padding (pad10*1). - Specification: NIST FIPS 202.
When to choose SHAKE. Pick SHAKE when an extendable-output function is genuinely required - KMAC inputs, post-quantum signature schemes, hash-based DRBGs, and any protocol that needs more than the fixed-length output of SHA-3 / SHA-256. For ordinary fixed-length hashing prefer SHA-3 (FIPS 202) or Blake3 (faster on commodity hardware). Use SHAKE128 when 128-bit security is sufficient and throughput matters; use SHAKE256 when the higher capacity is required.
Constructors
Shake()
Initializes a new instance of the Shake class with a 256-bit output using SHAKE128 internals.
public Shake()
Shake(int, int)
Initializes a new instance of the Shake class with the specified output size and security level.
public Shake(int outputBits, int securityLevel)
Parameters
outputBitsintThe desired output size in bits. Must be a positive value divisible by 8.
securityLevelintThe SHAKE security level in bits. Must be either 128 (SHAKE128, rate = 168 bytes) or 256 (SHAKE256, rate = 136 bytes).
Exceptions
- ArgumentOutOfRangeException
outputBitsis not a positive multiple of 8, orsecurityLevelis not 128 or 256.
Properties
AlgorithmName
Gets the canonical, fully-qualified algorithm name for this instance, including any size or variant qualifiers
(for example, "Tiger/192", "Skein-512-256", "BLAKE2b-512", "ASCON-HASH256",
"SipHash-2-4-64").
public override string AlgorithmName { get; }
Property Value
- string
A string identifying the algorithm and its current configuration.
Remarks
Derived classes implement this property to expose a stable, consumer-facing identifier suitable for logging, telemetry, registry keys, or interop with hash-name catalogues. Implementations should be pure and side-effect-free - the value may be queried before any input has been consumed and after disposal as part of error reporting.
CanReuseTransform
Gets a value indicating whether the current transform can be reused.
public override bool CanReuseTransform { get; }
Property Value
CanTransformMultipleBlocks
When overridden in a derived class, gets a value indicating whether multiple blocks can be transformed.
public override bool CanTransformMultipleBlocks { get; }
Property Value
HashSize
Gets or sets the size, in bits, of the final computed hash output.
public int HashSize { get; set; }
Property Value
- int
The current output size in bits. Must be a positive multiple of 8.
Remarks
Because SHAKE is an XOF, the output length may be changed freely between computations. The security level (and therefore the rate) is fixed at construction time and cannot be altered. Changing this property after input has already been absorbed throws CryptographicUnexpectedOperationException.
Exceptions
- ArgumentOutOfRangeException
The assigned value is not a positive multiple of 8.
- ObjectDisposedException
The algorithm instance has been disposed.
- CryptographicUnexpectedOperationException
The hash computation has already started and the algorithm is no longer reconfigurable.
SecurityLevel
Gets the security level, in bits, of the SHAKE variant in use.
public int SecurityLevel { get; }
Property Value
- int
Either 128 (SHAKE128) or 256 (SHAKE256).
Methods
Dispose(bool)
Releases the resources used by this instance and clears the internal sponge state.
protected override void Dispose(bool disposing)
Parameters
HashCore(ReadOnlySpan<byte>)
Consumes the supplied input span and updates the algorithm state. Derived classes implement the buffering loop appropriate to their family (immediate-fire-on-full-block for Merkle–Damgård hashes, defer-on-full-block for Blake-family hashes).
protected override void HashCore(ReadOnlySpan<byte> source)
Parameters
sourceReadOnlySpan<byte>The input bytes to consume. May be empty, partial, exact-block, or multi-block in length.
Remarks
This overload is re-marked abstract by the grandparent to force every derived base to provide an explicit
implementation. Without this, the default HashCore(ReadOnlySpan<byte>)
implementation would allocate a temporary byte array and call back into
HashCore(byte[], int, int), producing infinite recursion through the grandparent's forwarding
override.
HashFinal()
Finalizes the hash computation by applying SHAKE multi-rate padding, absorbing the final block, and squeezing the requested number of output bytes from the sponge state.
protected override byte[] HashFinal()
Returns
Initialize()
Resets the algorithm to its initial state by clearing the residual buffer and the running byte total. Derived
classes override this method, call base.Initialize() first, and then reset their own algorithm-specific
state (chaining variables, IV, key-derived schedule).
public override void Initialize()
Remarks
This method does not reset the State property explicitly on .NET 6+ targets —
the framework manages that transition. On earlier targets, derived classes that need the already-finalized guard
should reset their _finalized backing field from their own Initialize override.
Derived classes that need to validate state before the reset (for example, a keyed MAC that refuses to be
re-initialized when no key has been set) should perform that validation before calling base.Initialize().
Once the base call returns, the residual buffer is empty, Bodu.Security.Cryptography.BufferedBlockHashAlgorithm._residualBytes is 0, and
Bodu.Security.Cryptography.BufferedBlockHashAlgorithm._totalBytes is 0.
Exceptions
- ObjectDisposedException
The instance has been disposed.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |