# primitives/crypto-pwhash _(no submodules)_ ## Purpose `cryptoPwhashStr` and `cryptoPwhashStrVerify` expose libsodium's Argon2id password hashing via `crypto_pwhash_str` and `crypto_pwhash_str_verify`. Argon2id is the winner of the Password Hashing Competition (2015) and the recommended algorithm for password storage by OWASP and NIST SP 800-63B. The encoded hash string includes the algorithm identifier, salt, and cost parameters — it is self-contained and safe to store directly in a database. This eliminates a class of bugs where the salt or parameters are stored separately and can become desynchronised. ## Features - Argon2id password hashing via `crypto_pwhash_str` — salt generated internally. - Self-contained encoded output (≈97 chars) — includes algorithm, salt, opsLimit, memLimit. - Constant-time verification via `crypto_pwhash_str_verify`. - Configurable `opsLimit` and `memLimit` — defaults to `OPSLIMIT_INTERACTIVE` / `MEMLIMIT_INTERACTIVE`. - Async — calls `sodiumReady()` internally. - `cryptoPwhashStrVerify` returns `false` on any failure, never throws. ## Usage: Basic Example ```ts import { cryptoPwhashStr, cryptoPwhashStrVerify } from "@suaveplan/crypto-sodium/primitives/pwhash"; const password = new TextEncoder().encode("user-password-here"); const hash = await cryptoPwhashStr(password); // Store `hash` in your database. Later, at login: const valid = await cryptoPwhashStrVerify(hash, password); console.log(valid); // true ``` ## Usage: Advanced Example Higher-security settings for sensitive credential storage: ```ts import { cryptoPwhashStr, cryptoPwhashStrVerify } from "@suaveplan/crypto-sodium/primitives/pwhash"; const password = new TextEncoder().encode("admin-master-password"); // Sensitive account — use MODERATE or SENSITIVE preset values // crypto_pwhash_OPSLIMIT_MODERATE = 3, MEMLIMIT_MODERATE = 268435456 (256 MiB) const hash = await cryptoPwhashStr(password, { opsLimit: 3, memLimit: 268_435_456, }); // Verification automatically reads cost parameters from the hash string const ok = await cryptoPwhashStrVerify(hash, password); // Password rehashing: if ok but hash uses lower-cost params, rehash // (the encoded string embeds the params so you can detect this) ``` ## API Reference ### `cryptoPwhashStr(password, opts?): Promise` Hashes `password` with Argon2id. **Parameters:** - `password: Uint8Array` — Raw password bytes. - `opts.opsLimit?: number` — CPU/iteration cost. Default: `crypto_pwhash_OPSLIMIT_INTERACTIVE`. - `opts.memLimit?: number` — Memory cost in bytes. Default: `crypto_pwhash_MEMLIMIT_INTERACTIVE`. **Returns:** `Promise` — Argon2id-encoded hash string, safe for database storage. ### `cryptoPwhashStrVerify(hash, password): Promise` Verifies `password` against an encoded hash string. **Parameters:** - `hash: string` — Encoded hash from `cryptoPwhashStr`. - `password: Uint8Array` — Candidate password bytes. **Returns:** `Promise` — `true` if the password matches. Returns `false` (not throws) on any failure including malformed hash strings. ### `interface PwhashOptions` - `opsLimit?: number` - `memLimit?: number` ## Implementation Notes `crypto_pwhash_str` generates a random salt internally and encodes the full Argon2id parameter set into the output string. This is the `$argon2id$v=19$...` format, compatible with most password-hashing libraries. The salt is never exposed to the caller. `crypto_pwhash_str_verify` uses constant-time comparison for the hash check. The `try/catch` maps libsodium exceptions (e.g., malformed hash strings, wrong length) to `false` for uniform API behaviour. The interactive preset (`OPSLIMIT_INTERACTIVE`, `MEMLIMIT_INTERACTIVE`) is calibrated for ≈50 ms on typical hardware. Increase `opsLimit` and `memLimit` for stored API keys, encryption master passwords, or recovery codes.