mirror of
https://github.com/UneBaguette/blake3.wasm.git
synced 2026-08-18 00:00:16 +02:00
feat: camelCase JS exports, node-esm, index entry point
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
# blake3 to wasm
|
||||
# blake3-wasm-rs
|
||||
|
||||
[](https://www.npmjs.com/package/blake3-wasm-rs)
|
||||
[](https://github.com/UneBaguette/blake3.wasm/actions/workflows/ci.yml)
|
||||
[](https://github.com/UneBaguette/blake3.wasm/blob/master/LICENSE)
|
||||
[](https://www.npmjs.com/package/blake3-wasm-rs)
|
||||
|
||||
**blake3.wasm** is a WebAssembly port of the BLAKE3 cryptographic hash function written in **Rust**. It enables fast and secure hashing right inside **browsers** and **Node.js**.
|
||||
**blake3-wasm-rs** is a WebAssembly port of the BLAKE3 cryptographic hash function written in **Rust**. It enables fast and secure hashing right inside **browsers** and **Node.js**.
|
||||
|
||||
## build
|
||||
|
||||
@@ -36,43 +36,125 @@ const key = new Uint8Array(32).fill(1);
|
||||
|
||||
// One-shot hashing
|
||||
blake3.hash(data);
|
||||
blake3.hashXof(data, 64); // variable output length
|
||||
|
||||
// MAC and key derivation
|
||||
blake3.keyedHash(data, key);
|
||||
blake3.hashXof(data, 64); // variable output length
|
||||
blake3.keyedHash(data, key); // key must be exactly 32 bytes
|
||||
blake3.deriveKey('my context', key);
|
||||
|
||||
// Conctruct for streaming
|
||||
const hasher = new blake3.Hasher();
|
||||
|
||||
hasher.update(data.slice(0, 5));
|
||||
hasher.update(data.slice(5));
|
||||
hasher.finalize();
|
||||
```
|
||||
|
||||
#### OR
|
||||
|
||||
```js
|
||||
import { hash, hashXof, keyedHash, deriveKey, Hasher } from 'blake3-wasm-rs'
|
||||
|
||||
const data = new TextEncoder().encode('hello world')
|
||||
const key = new Uint8Array(32).fill(1)
|
||||
|
||||
// One-shot hashing
|
||||
hash(data)
|
||||
hashXof(data, 64) // variable output length
|
||||
|
||||
// MAC and key derivation
|
||||
keyedHash(data, key)
|
||||
deriveKey('my context', key)
|
||||
// Conctruct for Streaming
|
||||
{
|
||||
using h = new blake3.Hasher();
|
||||
h.update(data.slice(0, 5));
|
||||
h.update(data.slice(5));
|
||||
h.finalize();
|
||||
h.finalizeXof(64);
|
||||
h.reset();
|
||||
}
|
||||
|
||||
// Streaming
|
||||
const h = new Hasher()
|
||||
h.update(data.slice(0, 5))
|
||||
h.update(data.slice(5))
|
||||
h.finalize()
|
||||
// Keyed (MAC mode)
|
||||
{
|
||||
using mac = blake3.Hasher.newKeyed(key);
|
||||
mac.update(data);
|
||||
mac.finalize();
|
||||
}
|
||||
|
||||
// Streaming
|
||||
// Key derivation mode
|
||||
{
|
||||
using kdf = blake3.Hasher.newDeriveKey('my app v1 :: subkey');
|
||||
kdf.update(key);
|
||||
kdf.finalize();
|
||||
}
|
||||
|
||||
// Batch hashing without re-allocating
|
||||
{
|
||||
using h = new blake3.Hasher();
|
||||
h.update(chunk1);
|
||||
const first = h.finalizeAndReset();
|
||||
h.update(chunk2);
|
||||
const second = h.finalizeAndReset();
|
||||
}
|
||||
```
|
||||
|
||||
#### Named imports
|
||||
|
||||
```ts
|
||||
import { hash, hashXof, keyedHash, deriveKey, Hasher } from 'blake3-wasm-rs';
|
||||
|
||||
const data = new TextEncoder().encode('hello world');
|
||||
const key = new Uint8Array(32).fill(1);
|
||||
|
||||
// One-shot hashing
|
||||
hash(data);
|
||||
hashXof(data, 64); // variable output length
|
||||
keyedHash(data, key); // key must be exactly 32 bytes
|
||||
deriveKey('my context', key);
|
||||
|
||||
// Streaming
|
||||
{
|
||||
using h = new Hasher();
|
||||
h.update(data.slice(0, 5));
|
||||
h.update(data.slice(5));
|
||||
h.finalize();
|
||||
h.finalizeXof(64);
|
||||
h.reset();
|
||||
}
|
||||
|
||||
// Keyed (MAC mode)
|
||||
{
|
||||
using mac = Hasher.newKeyed(key);
|
||||
mac.update(data);
|
||||
mac.finalize();
|
||||
}
|
||||
|
||||
// Key derivation mode
|
||||
{
|
||||
using kdf = Hasher.newDeriveKey('my app v1 :: subkey');
|
||||
kdf.update(key);
|
||||
kdf.finalize();
|
||||
}
|
||||
|
||||
// Batch hashing without re-allocating
|
||||
{
|
||||
using h = new Hasher();
|
||||
h.update(chunk1);
|
||||
const first = h.finalizeAndReset();
|
||||
h.update(chunk2);
|
||||
const second = h.finalizeAndReset();
|
||||
}
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Functions
|
||||
|
||||
| Function | Returns | Description |
|
||||
|-----------------------------------|--------------|-------------------------------------------------|
|
||||
| `hash(data)` | `Uint8Array` | One-shot 32-byte BLAKE3 digest |
|
||||
| `hashXof(data, outLen)` | `Uint8Array` | Variable-length digest (XOF mode) |
|
||||
| `keyedHash(data, key)` | `Uint8Array` | Keyed hash / MAC (key must be exactly 32 bytes) |
|
||||
| `deriveKey(context, keyMaterial)` | `Uint8Array` | Derive a 32-byte subkey |
|
||||
|
||||
### Hasher class
|
||||
|
||||
| Method | Returns | Description |
|
||||
|--------------------------------|--------------|-----------------------------------------------------------|
|
||||
| `new Hasher()` | `Hasher` | Streaming hasher, unkeyed |
|
||||
| `Hasher.newKeyed(key)` | `Hasher` | Streaming hasher, MAC mode (key must be exactly 32 bytes) |
|
||||
| `Hasher.newDeriveKey(context)` | `Hasher` | Streaming hasher, KDF mode |
|
||||
| `.update(data)` | `void` | Feed data, can be called multiple times |
|
||||
| `.finalize()` | `Uint8Array` | 32-byte digest, non-destructive |
|
||||
| `.finalizeXof(outLen)` | `Uint8Array` | Variable-length digest, non-destructive |
|
||||
| `.finalizeAndReset()` | `Uint8Array` | Finalize then reset (useful for batch hashing) |
|
||||
| `.reset()` | `void` | Reset to initial state, preserves mode |
|
||||
| `.free()` | `void` | Release WASM memory manually (prefer `using` instead) |
|
||||
|
||||
> **Memory management:** In all modern browsers (and wasm-bindgen ≥ 0.2.91), WASM memory is freed automatically via the TC39 weak references proposal when the JS object goes out of scope.
|
||||
>
|
||||
> In practice, you often don't need to think about this. For deterministic cleanup or environments without weak reference support (older browsers, some Node.js setups), use `using` (TypeScript 5.2+ / ES2026) or call `.free()` manually.
|
||||
>
|
||||
> Never call `.free()` on a `using`-managed instance otherwise it will double-free.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Tested on **Apple M4**, Node.js v24.
|
||||
|
||||
Reference in New Issue
Block a user