https://github.com/soenneker/soenneker.hashing.blake3
A utility library for BLAKE3 hashing and verification
https://github.com/soenneker/soenneker.hashing.blake3
blake blake3 blake3util csharp dotnet hash hashing util
Last synced: about 2 months ago
JSON representation
A utility library for BLAKE3 hashing and verification
- Host: GitHub
- URL: https://github.com/soenneker/soenneker.hashing.blake3
- Owner: soenneker
- License: mit
- Created: 2026-03-01T20:23:07.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-05-01T01:07:30.000Z (about 2 months ago)
- Last Synced: 2026-05-01T02:20:28.319Z (about 2 months ago)
- Topics: blake, blake3, blake3util, csharp, dotnet, hash, hashing, util
- Language: C#
- Homepage: https://soenneker.com
- Size: 189 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: .github/CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: .github/CODE_OF_CONDUCT.md
- Security: .github/SECURITY.md
Awesome Lists containing this project
README
[](https://www.nuget.org/packages/soenneker.hashing.blake3/)
[](https://github.com/soenneker/soenneker.hashing.blake3/actions/workflows/publish-package.yml)
[](https://www.nuget.org/packages/soenneker.hashing.blake3/)
[](https://github.com/soenneker/soenneker.hashing.blake3/actions/workflows/codeql.yml)
#  Soenneker.Hashing.Blake3
A high-performance .NET library for **BLAKE3** hashing and constant-time verification. Pure C# with optional SIMD acceleration (AVX2 on x64, NEON on ARM).
## Features
- **BLAKE3** — 256-bit cryptographic hash; fast, secure, and specified in [the official BLAKE3 spec](https://github.com/BLAKE3-team/BLAKE3-specs).
- **Zero dependencies** — only the .NET runtime; no native or third-party packages.
- **SIMD** — uses AVX2 (x64) and NEON (ARM) when available for faster chunk hashing.
- **Parallel hashing** — `HashParallel` for large inputs; multi-threaded with batched SIMD where applicable.
- **Span/Memory-friendly** — hashing from `byte[]`, `ReadOnlySpan`, `ReadOnlyMemory`, and in-place digest writing.
- **Strings** — hash UTF-8 strings and get hex output via `Hash(string)` and `HashToString(string)`.
- **Constant-time verification** — `Verify` uses `CryptographicOperations.FixedTimeEquals` for digest comparison.
- **Blake3Util** — optional DI-registered utility for **file and directory** hashing (hash single files, whole directories, or an aggregate hash of a directory).
## Installation
```bash
dotnet add package Soenneker.Hashing.Blake3
```
## Quick Start
```csharp
using Soenneker.Hashing.Blake3;
// Hash bytes → 32-byte digest
byte[] data = System.Text.Encoding.UTF8.GetBytes("hello world");
byte[] hash = Blake3Hasher.Hash(data);
// Hash string (UTF-8) → hex
string hex = Blake3Hasher.HashToString("hello world");
// e.g. "d74981efa70a0c0b14d123f472c6e570..."
// Verify digest (constant-time)
bool ok = Blake3Hasher.Verify(data, hash);
```
## Usage
### Hashing
| Method | Description |
|--------|-------------|
| `Hash(byte[] input)` | Hash and return a new 32-byte array. |
| `Hash(ReadOnlySpan input)` | Hash from span; returns 32-byte array. |
| `Hash(ReadOnlyMemory input)` | Hash from memory; returns 32-byte array. |
| `Hash(..., Span destination)` | Hash and write digest into `destination` (must be ≥ 32 bytes). |
| `Hash(string s)` | Hash UTF-8 bytes of the string; returns 32-byte array. |
| `Hash(ReadOnlySpan chars)` | Hash UTF-8 encoding of the character span. |
| `HashToString(string input)` | Hash string (UTF-8) and return 64-character lowercase hex. |
Single-chunk and multi-chunk inputs use a scalar path; no extra allocations for the common case.
### Parallel hashing (large inputs)
For large buffers, use the parallel API to spread work across cores and use SIMD batches where supported:
| Method | Description |
|--------|-------------|
| `HashParallel(byte[] input)` | Hash with parallel chunk processing; returns 32-byte array. |
| `HashParallel(ReadOnlyMemory input)` | Same, from `ReadOnlyMemory`. |
| `HashParallel(..., Span destination)` | Parallel hash into `destination` (≥ 32 bytes). |
| `HashParallelCopy(ReadOnlySpan input)` | Copies input then runs parallel hash (use when you only have a span of a large buffer). |
Parallelism kicks in when the input is large enough to form multiple chunks (e.g. > 4 KiB). For smaller inputs, the regular `Hash` methods are usually faster.
### Blake3Util (file and directory hashing)
For file-based workflows, register `Blake3Util` (e.g. via `Blake3UtilRegistrar`) and inject `IBlake3Util`. It can hash individual files, entire directories, or produce a single aggregate hash for a directory (useful for integrity checks of a folder’s contents).
| Method | Description |
|--------|-------------|
| `HashFile(path)` | Hash a file and return its BLAKE3 digest as a 64-character hex string. |
| `HashFileToByteArray(path)` | Hash a file and return the 32-byte digest. |
| `HashDirectory(path)` | Hash every file in a directory (recursive); returns a dictionary of file path → 32-byte digest. |
| `HashDirectoryToAggregateString(path)` | Hash all files in a directory (sorted by path), combine path + hash per file, then BLAKE3 the aggregate; returns a single 64-character hex string for the whole directory. |
All methods are async and accept an optional `CancellationToken`. Files that cannot be read (e.g. access denied) are skipped when hashing directories.
### Verification
All `Verify` overloads compare the computed BLAKE3 digest to an expected value in **constant time** (via `CryptographicOperations.FixedTimeEquals`). The expected digest must be 32 bytes (or 64 hex characters where applicable).
| Method | Description |
|--------|-------------|
| `Verify(ReadOnlySpan input, ReadOnlySpan expectedHash)` | Returns `true` if BLAKE3(input) equals `expectedHash` (32 bytes). |
| `Verify(byte[] input, byte[] expectedHash)` | Same for byte arrays. |
| `Verify(string input, ReadOnlySpan expectedHash)` | Hash UTF-8 string and compare to 32-byte digest. |
| `Verify(string input, string expectedHashHex)` | Hash UTF-8 string and compare to 64-char hex string (case-insensitive). |
## Output
- Digest length is **32 bytes** (256 bits), as per BLAKE3.
- Hex strings from `HashToString` are **64 lowercase** hex characters.