{"id":46597848,"url":"https://github.com/soenneker/soenneker.hashing.blake3","last_synced_at":"2026-05-03T08:05:57.561Z","repository":{"id":341497699,"uuid":"1170182675","full_name":"soenneker/soenneker.hashing.blake3","owner":"soenneker","description":"A utility library for BLAKE3 hashing and verification","archived":false,"fork":false,"pushed_at":"2026-05-01T01:07:30.000Z","size":194,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-01T02:20:28.319Z","etag":null,"topics":["blake","blake3","blake3util","csharp","dotnet","hash","hashing","util"],"latest_commit_sha":null,"homepage":"https://soenneker.com","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/soenneker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"soenneker","thanks_dev":"soenneker"}},"created_at":"2026-03-01T20:23:07.000Z","updated_at":"2026-05-01T00:53:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/soenneker/soenneker.hashing.blake3","commit_stats":null,"previous_names":["soenneker/soenneker.hashing.blake3"],"tags_count":42,"template":false,"template_full_name":null,"purl":"pkg:github/soenneker/soenneker.hashing.blake3","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soenneker%2Fsoenneker.hashing.blake3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soenneker%2Fsoenneker.hashing.blake3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soenneker%2Fsoenneker.hashing.blake3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soenneker%2Fsoenneker.hashing.blake3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/soenneker","download_url":"https://codeload.github.com/soenneker/soenneker.hashing.blake3/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soenneker%2Fsoenneker.hashing.blake3/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32560914,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blake","blake3","blake3util","csharp","dotnet","hash","hashing","util"],"created_at":"2026-03-07T15:05:35.934Z","updated_at":"2026-05-03T08:05:57.530Z","avatar_url":"https://github.com/soenneker.png","language":"C#","funding_links":["https://github.com/sponsors/soenneker","https://thanks.dev/soenneker"],"categories":[],"sub_categories":[],"readme":"[![](https://img.shields.io/nuget/v/soenneker.hashing.blake3.svg?style=for-the-badge)](https://www.nuget.org/packages/soenneker.hashing.blake3/)\n[![](https://img.shields.io/github/actions/workflow/status/soenneker/soenneker.hashing.blake3/publish-package.yml?style=for-the-badge)](https://github.com/soenneker/soenneker.hashing.blake3/actions/workflows/publish-package.yml)\n[![](https://img.shields.io/nuget/dt/soenneker.hashing.blake3.svg?style=for-the-badge)](https://www.nuget.org/packages/soenneker.hashing.blake3/)\n[![](https://img.shields.io/github/actions/workflow/status/soenneker/soenneker.hashing.blake3/codeql.yml?label=CodeQL\u0026style=for-the-badge)](https://github.com/soenneker/soenneker.hashing.blake3/actions/workflows/codeql.yml)\n\n# ![](https://user-images.githubusercontent.com/4441470/224455560-91ed3ee7-f510-4041-a8d2-3fc093025112.png) Soenneker.Hashing.Blake3\n\nA high-performance .NET library for **BLAKE3** hashing and constant-time verification. Pure C# with optional SIMD acceleration (AVX2 on x64, NEON on ARM).\n\n## Features\n\n- **BLAKE3** — 256-bit cryptographic hash; fast, secure, and specified in [the official BLAKE3 spec](https://github.com/BLAKE3-team/BLAKE3-specs).\n- **Zero dependencies** — only the .NET runtime; no native or third-party packages.\n- **SIMD** — uses AVX2 (x64) and NEON (ARM) when available for faster chunk hashing.\n- **Parallel hashing** — `HashParallel` for large inputs; multi-threaded with batched SIMD where applicable.\n- **Span/Memory-friendly** — hashing from `byte[]`, `ReadOnlySpan\u003cbyte\u003e`, `ReadOnlyMemory\u003cbyte\u003e`, and in-place digest writing.\n- **Strings** — hash UTF-8 strings and get hex output via `Hash(string)` and `HashToString(string)`.\n- **Constant-time verification** — `Verify` uses `CryptographicOperations.FixedTimeEquals` for digest comparison.\n- **Blake3Util** — optional DI-registered utility for **file and directory** hashing (hash single files, whole directories, or an aggregate hash of a directory).\n\n## Installation\n\n```bash\ndotnet add package Soenneker.Hashing.Blake3\n```\n\n## Quick Start\n\n```csharp\nusing Soenneker.Hashing.Blake3;\n\n// Hash bytes → 32-byte digest\nbyte[] data = System.Text.Encoding.UTF8.GetBytes(\"hello world\");\nbyte[] hash = Blake3Hasher.Hash(data);\n\n// Hash string (UTF-8) → hex\nstring hex = Blake3Hasher.HashToString(\"hello world\");\n// e.g. \"d74981efa70a0c0b14d123f472c6e570...\"\n\n// Verify digest (constant-time)\nbool ok = Blake3Hasher.Verify(data, hash);\n```\n\n## Usage\n\n### Hashing\n\n| Method | Description |\n|--------|-------------|\n| `Hash(byte[] input)` | Hash and return a new 32-byte array. |\n| `Hash(ReadOnlySpan\u003cbyte\u003e input)` | Hash from span; returns 32-byte array. |\n| `Hash(ReadOnlyMemory\u003cbyte\u003e input)` | Hash from memory; returns 32-byte array. |\n| `Hash(..., Span\u003cbyte\u003e destination)` | Hash and write digest into `destination` (must be ≥ 32 bytes). |\n| `Hash(string s)` | Hash UTF-8 bytes of the string; returns 32-byte array. |\n| `Hash(ReadOnlySpan\u003cchar\u003e chars)` | Hash UTF-8 encoding of the character span. |\n| `HashToString(string input)` | Hash string (UTF-8) and return 64-character lowercase hex. |\n\nSingle-chunk and multi-chunk inputs use a scalar path; no extra allocations for the common case.\n\n### Parallel hashing (large inputs)\n\nFor large buffers, use the parallel API to spread work across cores and use SIMD batches where supported:\n\n| Method | Description |\n|--------|-------------|\n| `HashParallel(byte[] input)` | Hash with parallel chunk processing; returns 32-byte array. |\n| `HashParallel(ReadOnlyMemory\u003cbyte\u003e input)` | Same, from `ReadOnlyMemory\u003cbyte\u003e`. |\n| `HashParallel(..., Span\u003cbyte\u003e destination)` | Parallel hash into `destination` (≥ 32 bytes). |\n| `HashParallelCopy(ReadOnlySpan\u003cbyte\u003e input)` | Copies input then runs parallel hash (use when you only have a span of a large buffer). |\n\nParallelism kicks in when the input is large enough to form multiple chunks (e.g. \u0026gt; 4 KiB). For smaller inputs, the regular `Hash` methods are usually faster.\n\n### Blake3Util (file and directory hashing)\n\nFor 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).\n\n| Method | Description |\n|--------|-------------|\n| `HashFile(path)` | Hash a file and return its BLAKE3 digest as a 64-character hex string. |\n| `HashFileToByteArray(path)` | Hash a file and return the 32-byte digest. |\n| `HashDirectory(path)` | Hash every file in a directory (recursive); returns a dictionary of file path → 32-byte digest. |\n| `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. |\n\nAll methods are async and accept an optional `CancellationToken`. Files that cannot be read (e.g. access denied) are skipped when hashing directories.\n\n### Verification\n\nAll `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).\n\n| Method | Description |\n|--------|-------------|\n| `Verify(ReadOnlySpan\u003cbyte\u003e input, ReadOnlySpan\u003cbyte\u003e expectedHash)` | Returns `true` if BLAKE3(input) equals `expectedHash` (32 bytes). |\n| `Verify(byte[] input, byte[] expectedHash)` | Same for byte arrays. |\n| `Verify(string input, ReadOnlySpan\u003cbyte\u003e expectedHash)` | Hash UTF-8 string and compare to 32-byte digest. |\n| `Verify(string input, string expectedHashHex)` | Hash UTF-8 string and compare to 64-char hex string (case-insensitive). |\n\n## Output\n\n- Digest length is **32 bytes** (256 bits), as per BLAKE3.\n- Hex strings from `HashToString` are **64 lowercase** hex characters.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoenneker%2Fsoenneker.hashing.blake3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoenneker%2Fsoenneker.hashing.blake3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoenneker%2Fsoenneker.hashing.blake3/lists"}