Blake3 Class
Definition
- Namespace
- Bodu.Security.Cryptography
- Assembly
- Bodu.Security.Cryptography.dll
- Package
- Bodu.Security.Cryptography 1.2.0
- Source
- Blake3.cs
Computes a 256-bit cryptographic hash using the BLAKE3 algorithm designed by Jack O'Connor, Jean-Philippe
Aumasson, Samuel Neves, and Zooko Wilcox-O'Hearn. This class cannot be inherited.
public sealed class Blake3 : DeferredFinalBlockHashAlgorithm, ICryptoTransform, IDisposable
- Inheritance
-
Blake3
- Implements
- Inherited Members
- Extension Methods
Examples
using var blake3 = new Blake3();
byte[] digest = blake3.ComputeHash(message);
Remarks
BLAKE3 is a cryptographic hash function that combines the speed of non-cryptographic hashes with strong security guarantees. It is based on a binary tree structure where each leaf (chunk) processes up to 1024 bytes of input and each internal (parent) node combines two child chaining values. All compression is performed by a single ARX-based function derived from the BLAKE2 and ChaCha families.
Input is divided into 1024-byte chunks, each compressed block-by-block into an 8-word (256-bit) chaining value. When
more than one chunk exists the chaining values are folded pairwise into parent nodes until a single root chaining
value remains. The root compression call is distinguished by the ROOT domain-separation flag, which enables
XOF-style output extraction; this implementation fixes the output length at 256 bits.
This implementation inherits its 64-byte residual buffer, running byte counter, and defer-on-full-block buffering loop from DeferredFinalBlockHashAlgorithm. The final 64-byte block is not compressed until HashFinal() is called, ensuring that chunk-level and tree-level domain flags can be applied correctly.
This implementation supports the standard, unkeyed hash mode only. Keyed-hash and key-derivation modes are not exposed.
Parameters at a glance.
- Output size: 256 bits (32 bytes), fixed.
- Block size: 64 bytes; chunk size: 1024 bytes (the leaf of the hash tree).
- Construction: binary Merkle tree over chunks, ARX compression derived from BLAKE2 / ChaCha.
- Mode: standard unkeyed hash only - keyed hash and KDF modes are not exposed.
When to choose BLAKE3. Reach for BLAKE3 when raw throughput on long inputs is the priority - its tree structure is naturally parallel-friendly and outperforms Blake2b, SHA-2, and SHA-3 on multi-megabyte messages. For short inputs the difference shrinks and any of the BLAKE2 / SHA-2 variants is fine. Use Blake2b if a configurable output size or RFC 7693-compatible MAC mode is required; use MerkleTree if you want RFC 6962's tree, its proofs, and explicit control over the block size and the underlying leaf hash.
Constructors
Blake3()
Initializes a new instance of the Blake3 class, configured to produce a 256-bit digest.
public Blake3()
Remarks
Every hash runs on the calling thread; see MaxDegreeOfParallelism.
Blake3(int)
Initializes a new instance of the Blake3 class, configured to produce a 256-bit digest, with the specified bound on the threads each write may use.
public Blake3(int maxDegreeOfParallelism)
Parameters
maxDegreeOfParallelismintThe greatest number of threads one write may use, the calling thread included;
-1for up to one per processor.
Remarks
The digest never depends on the bound; see MaxDegreeOfParallelism.
Exceptions
- ArgumentOutOfRangeException
maxDegreeOfParallelismis zero or less than-1.
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 this transform instance can be reused after a hash operation is completed.
public override bool CanReuseTransform { get; }
Property Value
CanTransformMultipleBlocks
Gets a value indicating whether multiple blocks may be transformed in a single TransformBlock(byte[], int, int, byte[], int) call.
public override bool CanTransformMultipleBlocks { get; }
Property Value
MaxDegreeOfParallelism
Gets the greatest number of threads one write may use to hash its input.
public int MaxDegreeOfParallelism { get; }
Property Value
- int
1, the default, hashes every write on the calling thread. A larger value, or-1for up to one thread per processor, lets the whole chunks of a large write be hashed on several threads at once. The digest never depends on this value.
Remarks
BLAKE3's tree makes every complete subtree independent of the others, so a large write is divided into parts of 64 KiB, claimed by the calling thread and the workers as each finishes the last, and the parts' chaining values are joined on the calling thread. A write of less than 256 KiB of whole chunks stays on the calling thread, where waking other threads would cost more than they save.
The default is 1 because a service that hashes many inputs at once already keeps every core busy, and
would only add hand-offs. Raise it to hash one large input faster: a file, a download, a snapshot.
Exceptions
- ObjectDisposedException
The 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.
HashCore(ReadOnlySpan<byte>)
Consumes the supplied input span. Whole chunks that start on a chunk boundary and are followed by more input are hashed as complete subtrees, many chunks at once; everything else goes through the block-by-block path of the base class, which keeps the final block deferred.
protected override void HashCore(ReadOnlySpan<byte> source)
Parameters
sourceReadOnlySpan<byte>The input bytes to consume. May be empty, partial, exact-block, or multi-chunk in length.
Exceptions
- ObjectDisposedException
The algorithm instance has been disposed.
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.
ProcessBlock(ReadOnlySpan<byte>, ulong, bool)
Advances the BLAKE3 compression state by one 64-byte block, applying the correct chunk-level and tree-level
domain flags derived from totalBytesIncludingThisBlock.
protected override void ProcessBlock(ReadOnlySpan<byte> block, ulong totalBytesIncludingThisBlock, bool isFinal)
Parameters
blockReadOnlySpan<byte>The 64-byte block to compress. Zero-padded by the base class when
isFinalis true and the final message byte count is not a multiple of 64.totalBytesIncludingThisBlockulongThe cumulative byte count including the bytes in this block. Used to derive the chunk index, the block position within the chunk, and the true block length for the final block.
isFinalbooltrue for the last compression call, raised by HashFinal(); otherwise false.
ProcessFinalBlock()
Extracts the digest from the algorithm's chaining variables after ProcessBlock(ReadOnlySpan<byte>, ulong, bool) has been called
with isFinal: true for the last time.
protected override byte[] ProcessFinalBlock()
Returns
- byte[]
A byte array containing the final computed hash value.
Remarks
This method is invoked once per HashFinal() call, immediately after the final compression. It reads from the internal hash state and serializes the result to a byte array in the format expected by consumers of the algorithm (typically little-endian for Blake-family hashes).
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |