UNPKG

yescrypt-wasm

Version:
120 lines (80 loc) 4.26 kB
# Yescrypt WebAssembly Module [![NPM Version](https://img.shields.io/npm/v/yescrypt-wasm)](https://www.npmjs.com/package/yescrypt-wasm) Yescrypt / Scrypt WebAssembly Module for Browsers / Node.js ## Prerequisites * Node.js LTS or Browser where WebAssembly is enabled ## Install ```bash $ yarn add yescrypt-wasm ``` or on html header / body ```html <script src="https://cdn.jsdelivr.net/npm/yescrypt-wasm/lib/yescrypt.umd.min.js"></script> ``` WASM file is fully embedded on script so that you need to load nothing (and should work with any bundlers without hassle) ## Build WASM (optional) Requires latest [Emscripten](https://emscripten.org/docs/getting_started/downloads.html) WASM compiler ```bash $ yarn && yarn build:wasm ``` Will update .wasm and bundled files ## Build library (optional) Rebuild node.js and web umd bundle files ```bash $ yarn && yarn build ``` ## Example Code ```js import { Yescrypt, bytesToHex } from './lib/index.js'; const getRandomHex = () => Buffer.from(crypto.getRandomValues(new Uint8Array(32))); async function test() { const yescrypt = await Yescrypt.init(); const passwd = Buffer.from("7000000001e980924e4e1109230383e66d62945ff8e749903bea4336755c00000000000051928aff1b4d72416173a8c3948159a09a73ac3bb556aa6bfbcad1a85da7f4c1d13350531e24031b939b9e2b", "hex"); console.log(bytesToHex(yescrypt.yescrypt_kdf(passwd, getRandomHex()))) } test(); ``` Also refer `example.html` for example of using it on browser. ## API All four methods take the password and salt as `Uint8Array`/`Buffer` and honor the explicit byte length (binary-safe — a password containing or sized past a NUL byte is hashed correctly): ```ts yescrypt.scrypt_kdf (passwd, salt, N?, r?, p?, t?, flags?, g?, dklen?): Uint8Array yescrypt.yescrypt_kdf(passwd, salt, N?, r?, p?, t?, flags?, g?, dklen?): Uint8Array yescrypt.scrypt_hash (passwd, salt, N?, r?, p?, t?, flags?, g?): string // "$y$..." crypt(3) form yescrypt.yescrypt_hash(passwd, salt, N?, r?, p?, t?, flags?, g?): string ``` These map directly onto the C `yescrypt_params_t` (`yescrypt-c/yescrypt.h`): | param | meaning | default (`scrypt_*` / `yescrypt_*`) | |---------|-------------------------------------------|-------------------------------------| | `N` | cost (power of two) | `4096` | | `r` | block size | `32` | | `p` | parallelism | `1` | | `t` | extra time without extra memory | `0` | | `flags` | mode/flavor (see `YESCRYPT_*` constants) | `0` / `YESCRYPT_DEFAULTS` | | `g` | hash-upgrade count | `0` | | `dklen` | output length in bytes (`*_kdf` only) | `64` | Flag constants are exported (`YESCRYPT_WORM`, `YESCRYPT_RW`, `YESCRYPT_DEFAULTS`, the `YESCRYPT_ROUNDS_*` / `GATHER_*` / `SIMPLE_*` / `SBOX_*` family) and may be OR'ed together to match any C-side configuration. ROM (`NROM` / shared) is not yet exposed. Invalid parameters throw a `RangeError` (`N` must be a power of two `> 1`, `r * p < 2^30`), and a genuine hashing failure throws an `Error` rather than returning a zeroed/empty result. The WASM module is built with `ALLOW_MEMORY_GROWTH`, so larger `N`/`r` no longer abort the whole instance — they either succeed or surface an out-of-memory `Error`. ```js import { Yescrypt, YESCRYPT_DEFAULTS, YESCRYPT_WORM } from './lib/index.js'; const y = await Yescrypt.init(); const passwd = Buffer.from('a'.repeat(20)); // 20-byte password works correctly const salt = Buffer.from(crypto.getRandomValues(new Uint8Array(16))); // crypt(3)-style encoded hash for /etc/shadow (yescrypt defaults): console.log(y.yescrypt_hash(passwd, salt)); // raw 32-byte KDF output with custom flags: console.log(y.yescrypt_kdf(passwd, salt, 4096, 32, 1, 0, YESCRYPT_DEFAULTS, 0, 32)); ``` ## References [Yescrypt](https://github.com/openwall/yescrypt) [scrypt-js](https://github.com/ricmoo/scrypt-js) [scrypt-wasm](https://github.com/MyEtherWallet/scrypt-wasm)