Skip to content

lamb356/blake3-wasm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BLAKE3 WASM — Auditable Build

Minimal wrapper around the official BLAKE3 hash function for browser use. No pre-built WASM is committed — auditors build from source.

Security Audit Guide

  1. build.sh (~80 lines) — clones BLAKE3 at tag 1.8.3 (pinned), scaffolds two tiny Rust crates, builds with wasm-pack, cleans up
  2. blake3-wasm-single/src/lib.rs — 7 lines: calls blake3::hash() and returns bytes
  3. blake3-wasm-rayon/src/lib.rs — 22 lines: uses blake3::Hasher with update_rayon() for parallel hashing above 16 KB
  4. Run ./build.sh (or .\build.ps1 on Windows) to build from source
  5. All Cargo.toml, config, and source files are generated by the build script — nothing hidden

Build Prerequisites

Build

# Linux/macOS
chmod +x build.sh
./build.sh

# Windows (PowerShell)
.\build.ps1

Browser Demo

After building, serve the directory and open browser-test.html:

python -m http.server 8080
# Open http://localhost:8080/browser-test.html

Drop a file to compare BLAKE3 (WASM) vs SHA-256 (WebCrypto) throughput.

  • If SharedArrayBuffer is available: parallel mode (auto-detected thread count)
  • Otherwise: single-threaded SIMD fallback
  • Thread count can be changed via the dropdown selector (persists in URL hash)

What Gets Built

blake3-wasm-single/pkg/   — single-threaded WASM module
blake3-wasm-rayon/pkg/    — parallel (rayon) WASM module

Both are gitignored. Build from source to verify.

Design Decisions

Decision Rationale
No pre-built WASM Auditors build from source to verify nothing is tampered
Build script generates all config Only build.sh + build.ps1 to audit
Pin BLAKE3 at tag 1.8.3 Reproducible builds; matches crates.io
Two builds (single + rayon) browser-test.html auto-falls back; both wrappers are tiny
Rayon uses nightly-2025-11-15 Required for build-std with atomics/shared-memory
WASM memory capped at 64 MB Prevents OOM on mobile (iPhones reject 1 GB allocations)
Thread count auto-detected Uses navigator.hardwareConcurrency; user can override via selector

Self-Hosted Deployment

The parallel (rayon) WASM build requires SharedArrayBuffer, which browsers only enable when both of these response headers are present:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

Nginx

server {
    # ... existing config ...
    add_header Cross-Origin-Opener-Policy "same-origin" always;
    add_header Cross-Origin-Embedder-Policy "require-corp" always;
}

Apache

<IfModule mod_headers.c>
    Header always set Cross-Origin-Opener-Policy "same-origin"
    Header always set Cross-Origin-Embedder-Policy "require-corp"
</IfModule>

Cloudflare Pages

Create a _headers file in the publish directory:

/*
  Cross-Origin-Opener-Policy: same-origin
  Cross-Origin-Embedder-Policy: require-corp

Static Hosting (GitHub Pages, S3, etc.)

If you can't set response headers, the repo includes coi-serviceworker.min.js which injects the headers client-side on the second page load. The demo page loads it automatically — no extra configuration needed. The single-threaded fallback works immediately on the first load.

Memory Configuration

The rayon build sets --max-memory=67108864 (64 MB) in the linker args. This limits the maximum hashable file size to ~60 MB (wasm-bindgen copies the input into WASM linear memory). To increase this, edit the --max-memory value in build.sh (line 87) or build.ps1 (line 106) and rebuild:

# Example: 256 MB
"-C", "link-arg=--max-memory=268435456",

Note: Values above ~256 MB may fail to allocate on mobile devices.

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages