164 lines
17 KiB
Markdown
164 lines
17 KiB
Markdown
# @suaveplan/password-generator - Cryptographically-strong password and passphrase generator — char-class, pronounceable, EFF Diceware, PIN, entropy estimator. Universal, zero browser/Node deps.
|
||
|
||
## Summary
|
||
|
||
Cryptographically-strong password and passphrase generator — char-class,
|
||
pronounceable, EFF Diceware, and PIN modes with bias-free RNG, real entropy
|
||
estimates, and injectable `Rng` for deterministic replay. Universal
|
||
(zero browser / Node / React deps).
|
||
|
||
The package owns the surface end-to-end: bundled EFF Long (7776) and EFF
|
||
Short 1 (1296) wordlists, Lemire-style rejection-sampling `randomInt` for
|
||
unbiased integer draws, Fisher-Yates shuffle, char-class quotas, configurable
|
||
passphrase decoration, an entropy estimator, and a `assertStrength` guard.
|
||
|
||
<!-- begin:auto-docs -->
|
||
## Documentation tree
|
||
|
||
- [charsets](./src/charsets/charsets.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [charsets](./src/charsets/charsets.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [entropy](./src/entropy/entropy.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [entropy](./src/entropy/entropy.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [errors](./src/errors/codes.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [codes](./src/errors/codes.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [observability](./src/observability/metrics.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [metrics](./src/observability/metrics.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [passphrase](./src/passphrase/passphrase.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [passphrase](./src/passphrase/passphrase.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [password](./src/password/password.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs --> - pronounceable — `generatePronounceablePassword(opts…
|
||
- [password](./src/password/password.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs --> - pronounceable — `generatePronounceablePassword(opts…
|
||
- [pronounceable](./src/password/pronounceable.md) — `generatePronounceablePassword(opts, rng?)` emits CVC-pattern (consonant–vowel–consonant) syllables suitable for should…
|
||
- [pin](./src/pin/pin.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [pin](./src/pin/pin.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [default-rng](./src/random/default-rng.md) — `defaultRng()` builds the default `Rng` backed by `@suaveplan/crypto-utils.randomBytes`, which delegates to `crypto.get…
|
||
- [fisher-yates](./src/random/fisher-yates.md) — `shuffleInPlace(array, rng)` performs an in-place Fisher–Yates / Knuth shuffle parameterised over the bias-free `random…
|
||
- [random-int](./src/random/random-int.md) — `randomInt(rng, max)` returns a uniformly-distributed integer in the half-open interval `[0, max)` for any `max ∈ [1, 2…
|
||
- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
||
- [eff-long](./src/wordlists/eff-long.md) — Bundles the EFF Long Wordlist as a frozen `readonly string[]` so callers who only want passphrase generation pull this…
|
||
- [eff-short](./src/wordlists/eff-short.md) — Bundles EFF's Short Wordlist #1 — 1296 entries (4-dice / 6⁴), ≈ 10.34 bits/word, every entry ≤ 5 ASCII characters. Sour…
|
||
- [registry](./src/wordlists/registry.md) — The wordlist registry exposes a small plugin API — `registerWordlist`, `getWordlist`, `listWordlists` — that lets calle…
|
||
<!-- end:auto-docs --> - [charsets](./src/charsets/charsets.md) — <!-- begin:auto-docs --> _(no submodules)_- [entropy](./src/entropy/entropy.md) — <!-- begin:auto-docs --> _(no submodules)_- [entropy](./src/entropy/entropy.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [metrics](./src/observability/metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [passphrase](./src/passphrase/passphrase.md) — <!-- begin:auto-docs --> _(no submodules)_- [passphrase](./src/passphrase/passphrase.md) — <!-- begin:auto-docs --> _(no submodules)_- [password](./src/password/password.md) — <!-- begin:auto-docs --> _(no submodules)_- pronounceable — `generatePronounceablePassword(opts…
|
||
- [password](./src/password/password.md) — <!-- begin:auto-docs --> _(no submodules)_- pronounceable — `generatePronounceablePassword(opts…
|
||
- [pronounceable](./src/password/pronounceable.md) — `generatePronounceablePassword(opts, rng?)` emits CVC-pattern (consonant–vowel–consonant) syllables suitable for should…
|
||
- [pin](./src/pin/pin.md) — <!-- begin:auto-docs --> _(no submodules)_- [pin](./src/pin/pin.md) — <!-- begin:auto-docs --> _(no submodules)_- [default-rng](./src/random/default-rng.md) — `defaultRng()` builds the default `Rng` backed by `@suaveplan/crypto-utils.randomBytes`, which delegates to `crypto.get…
|
||
- [fisher-yates](./src/random/fisher-yates.md) — `shuffleInPlace(array, rng)` performs an in-place Fisher–Yates / Knuth shuffle parameterised over the bias-free `random…
|
||
- [random-int](./src/random/random-int.md) — `randomInt(rng, max)` returns a uniformly-distributed integer in the half-open interval `[0, max)` for any `max ∈ [1, 2…
|
||
- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [eff-long](./src/wordlists/eff-long.md) — Bundles the EFF Long Wordlist as a frozen `readonly string[]` so callers who only want passphrase generation pull this…
|
||
- [eff-short](./src/wordlists/eff-short.md) — Bundles EFF's Short Wordlist #1 — 1296 entries (4-dice / 6⁴), ≈ 10.34 bits/word, every entry ≤ 5 ASCII characters. Sour…
|
||
- [registry](./src/wordlists/registry.md) — The wordlist registry exposes a small plugin API — `registerWordlist`, `getWordlist`, `listWordlists` — that lets calle…
|
||
- [charsets](./src/charsets/charsets.md) — <!-- begin:auto-docs --> _(no submodules)_- [entropy](./src/entropy/entropy.md) — <!-- begin:auto-docs --> _(no submodules)_- [entropy](./src/entropy/entropy.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [metrics](./src/observability/metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [passphrase](./src/passphrase/passphrase.md) — <!-- begin:auto-docs --> _(no submodules)_- [passphrase](./src/passphrase/passphrase.md) — <!-- begin:auto-docs --> _(no submodules)_- [password](./src/password/password.md) — <!-- begin:auto-docs --> _(no submodules)_- pronounceable — `generatePronounceablePassword(opts…
|
||
- [password](./src/password/password.md) — <!-- begin:auto-docs --> _(no submodules)_- pronounceable — `generatePronounceablePassword(opts…
|
||
- [pronounceable](./src/password/pronounceable.md) — `generatePronounceablePassword(opts, rng?)` emits CVC-pattern (consonant–vowel–consonant) syllables suitable for should…
|
||
- [pin](./src/pin/pin.md) — <!-- begin:auto-docs --> _(no submodules)_- [pin](./src/pin/pin.md) — <!-- begin:auto-docs --> _(no submodules)_- [default-rng](./src/random/default-rng.md) — `defaultRng()` builds the default `Rng` backed by `@suaveplan/crypto-utils.randomBytes`, which delegates to `crypto.get…
|
||
- [fisher-yates](./src/random/fisher-yates.md) — `shuffleInPlace(array, rng)` performs an in-place Fisher–Yates / Knuth shuffle parameterised over the bias-free `random…
|
||
- [random-int](./src/random/random-int.md) — `randomInt(rng, max)` returns a uniformly-distributed integer in the half-open interval `[0, max)` for any `max ∈ [1, 2…
|
||
- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [eff-long](./src/wordlists/eff-long.md) — Bundles the EFF Long Wordlist as a frozen `readonly string[]` so callers who only want passphrase generation pull this…
|
||
- [eff-short](./src/wordlists/eff-short.md) — Bundles EFF's Short Wordlist #1 — 1296 entries (4-dice / 6⁴), ≈ 10.34 bits/word, every entry ≤ 5 ASCII characters. Sour…
|
||
- [registry](./src/wordlists/registry.md) — The wordlist registry exposes a small plugin API — `registerWordlist`, `getWordlist`, `listWordlists` — that lets calle…
|
||
- [charsets](./src/charsets/charsets.md) — <!-- begin:auto-docs --> _(no submodules)_- [entropy](./src/entropy/entropy.md) — <!-- begin:auto-docs --> _(no submodules)_- [entropy](./src/entropy/entropy.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [codes](./src/errors/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [metrics](./src/observability/metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [passphrase](./src/passphrase/passphrase.md) — <!-- begin:auto-docs --> _(no submodules)_- [passphrase](./src/passphrase/passphrase.md) — <!-- begin:auto-docs --> _(no submodules)_- [password](./src/password/password.md) — <!-- begin:auto-docs --> _(no submodules)_- pronounceable — `generatePronounceablePassword(opts…
|
||
- [password](./src/password/password.md) — <!-- begin:auto-docs --> _(no submodules)_- pronounceable — `generatePronounceablePassword(opts…
|
||
- [pronounceable](./src/password/pronounceable.md) — `generatePronounceablePassword(opts, rng?)` emits CVC-pattern (consonant–vowel–consonant) syllables suitable for should…
|
||
- [pin](./src/pin/pin.md) — <!-- begin:auto-docs --> _(no submodules)_- [pin](./src/pin/pin.md) — <!-- begin:auto-docs --> _(no submodules)_- [default-rng](./src/random/default-rng.md) — `defaultRng()` builds the default `Rng` backed by `@suaveplan/crypto-utils.randomBytes`, which delegates to `crypto.get…
|
||
- [fisher-yates](./src/random/fisher-yates.md) — `shuffleInPlace(array, rng)` performs an in-place Fisher–Yates / Knuth shuffle parameterised over the bias-free `random…
|
||
- [random-int](./src/random/random-int.md) — `randomInt(rng, max)` returns a uniformly-distributed integer in the half-open interval `[0, max)` for any `max ∈ [1, 2…
|
||
- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [eff-long](./src/wordlists/eff-long.md) — Bundles the EFF Long Wordlist as a frozen `readonly string[]` so callers who only want passphrase generation pull this…
|
||
- [eff-short](./src/wordlists/eff-short.md) — Bundles EFF's Short Wordlist #1 — 1296 entries (4-dice / 6⁴), ≈ 10.34 bits/word, every entry ≤ 5 ASCII characters. Sour…
|
||
- [registry](./src/wordlists/registry.md) — The wordlist registry exposes a small plugin API — `registerWordlist`, `getWordlist`, `listWordlists` — that lets calle…
|
||
- [charsets](./src/charsets/charsets.md) — <!-- begin:auto-docs --> _(no submodules)_- [entropy](./src/entropy/entropy.md) — <!-- begin:auto-docs --> _(no submodules)_ - [entropy](./src/entropy/entropy.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/codes.md) — <!-- begin:auto-docs --> _(no submodules)_ - [codes](./src/errors/codes.md) — <!-- begin:auto-docs --> _(no submodules)_- [observability](./src/observability/metrics.md) — <!-- begin:auto-docs --> _(no submodules)_ - [metrics](./src/observability/metrics.md) — <!-- begin:auto-docs --> _(no submodules)_- [passphrase](./src/passphrase/passphrase.md) — <!-- begin:auto-docs --> _(no submodules)_ - [passphrase](./src/passphrase/passphrase.md) — <!-- begin:auto-docs --> _(no submodules)_- [password](./src/password/password.md) — <!-- begin:auto-docs --> _(no submodules)_ - [password](./src/password/password.md) — <!-- begin:auto-docs --> _(no submodules)_ - [pronounceable](./src/password/pronounceable.md) — `generatePronounceablePassword(opts, rng?)` emits CVC-pattern (consonant–vowel–consonant) syllables suitable for should…
|
||
- [pin](./src/pin/pin.md) — <!-- begin:auto-docs --> _(no submodules)_ - [pin](./src/pin/pin.md) — <!-- begin:auto-docs --> _(no submodules)_- [default-rng](./src/random/default-rng.md) — `defaultRng()` builds the default `Rng` backed by `@suaveplan/crypto-utils.randomBytes`, which delegates to `crypto.get…
|
||
- [fisher-yates](./src/random/fisher-yates.md) — `shuffleInPlace(array, rng)` performs an in-place Fisher–Yates / Knuth shuffle parameterised over the bias-free `random…
|
||
- [random-int](./src/random/random-int.md) — `randomInt(rng, max)` returns a uniformly-distributed integer in the half-open interval `[0, max)` for any `max ∈ [1, 2…
|
||
- [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_ - [schemas](./src/schemas/schemas.md) — <!-- begin:auto-docs --> _(no submodules)_- [eff-long](./src/wordlists/eff-long.md) — Bundles the EFF Long Wordlist as a frozen `readonly string[]` so callers who only want passphrase generation pull this…
|
||
- [eff-short](./src/wordlists/eff-short.md) — Bundles EFF's Short Wordlist #1 — 1296 entries (4-dice / 6⁴), ≈ 10.34 bits/word, every entry ≤ 5 ASCII characters. Sour…
|
||
- [registry](./src/wordlists/registry.md) — The wordlist registry exposes a small plugin API — `registerWordlist`, `getWordlist`, `listWordlists` — that lets calle…
|
||
|
||
## Install
|
||
|
||
```bash
|
||
bun add @suaveplan/password-generator
|
||
```
|
||
|
||
## Quick Start
|
||
|
||
```ts
|
||
import {
|
||
assertStrength,
|
||
estimateEntropy,
|
||
generatePassphrase,
|
||
generatePassword,
|
||
generatePin,
|
||
} from "@suaveplan/password-generator";
|
||
|
||
// Char-class password
|
||
const pw = generatePassword({
|
||
length: 16,
|
||
requireLowercase: true,
|
||
requireUppercase: true,
|
||
requireDigits: true,
|
||
requireSymbols: true,
|
||
});
|
||
|
||
// 6-word EFF Long passphrase (≈ 77.5 bits)
|
||
const phrase = generatePassphrase({});
|
||
|
||
// 6-digit PIN
|
||
const pin = generatePin(6);
|
||
|
||
// Strength check
|
||
assertStrength(pw, 80); // throws PWGEN.STRENGTH_INSUFFICIENT if < 80 bits
|
||
const { bits, charsetSize } = estimateEntropy(pw);
|
||
```
|
||
|
||
## Tree-Shaking
|
||
|
||
Each major surface ships at its own subpath so consumers pull only what they
|
||
need:
|
||
|
||
```ts
|
||
import { generatePassword } from "@suaveplan/password-generator/password";
|
||
import { generatePassphrase } from "@suaveplan/password-generator/passphrase";
|
||
import { generatePin } from "@suaveplan/password-generator/pin";
|
||
import { EFF_LONG_WORDLIST } from "@suaveplan/password-generator/wordlists/eff-long";
|
||
import { EFF_SHORT_WORDLIST } from "@suaveplan/password-generator/wordlists/eff-short";
|
||
```
|
||
|
||
A consumer that imports only `./password` does not pull the 85 KB EFF Long
|
||
list. A consumer that imports only `./pin` pulls neither wordlist.
|
||
|
||
## Modules
|
||
|
||
- [`random/random-int`](./src/random/random-int.md) — bias-free `randomInt`
|
||
via Lemire rejection sampling.
|
||
- [`random/fisher-yates`](./src/random/fisher-yates.md) — Fisher-Yates shuffle
|
||
built on the unbiased picker.
|
||
- [`random/default-rng`](./src/random/default-rng.md) — default `Rng` wrapping
|
||
`@suaveplan/crypto-utils.randomBytes`.
|
||
- [`charsets/charsets`](./src/charsets/charsets.md) — `LOWERCASE` / `UPPERCASE`
|
||
/ `DIGITS` / `SYMBOLS` / `AMBIGUOUS` / `LOOKALIKES` + `buildEffectiveCharset`.
|
||
- [`password/password`](./src/password/password.md) — char-class generator with
|
||
required-class quotas.
|
||
- [`password/pronounceable`](./src/password/pronounceable.md) — CVC-pattern
|
||
pronounceable generator.
|
||
- [`passphrase/passphrase`](./src/passphrase/passphrase.md) — EFF Diceware
|
||
passphrase generator.
|
||
- [`pin/pin`](./src/pin/pin.md) — uniform digit-only PIN generator.
|
||
- [`entropy/entropy`](./src/entropy/entropy.md) — entropy estimator and
|
||
`assertStrength` guard.
|
||
- [`wordlists/eff-long`](./src/wordlists/eff-long.md) — bundled EFF Long
|
||
Wordlist (7776 entries).
|
||
- [`wordlists/eff-short`](./src/wordlists/eff-short.md) — bundled EFF Short
|
||
Wordlist 1 (1296 entries).
|
||
- [`wordlists/registry`](./src/wordlists/registry.md) — plugin API for caller-
|
||
supplied wordlists.
|
||
- [`errors/codes`](./src/errors/codes.md) — `PWGEN_CODES` registry and
|
||
`PwgenError` class.
|
||
- [`schemas/schemas`](./src/schemas/schemas.md) — Zod boundary schemas.
|
||
- [`observability/metrics`](./src/observability/metrics.md) — OpenTelemetry
|
||
histograms and counters.
|
||
|
||
## License
|
||
|
||
MIT
|
||
|