Skip to content
trevorbernardPublic

About

A diceware passphrase generator with selectable entropy sources — copies high-entropy passphrases straight to your clipboard

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

tumbler

CI Release

A diceware passphrase generator with selectable entropy sources. Generates memorable, high-entropy passphrases from the EFF large wordlist and copies them directly to your clipboard — no terminal output, no shell history.

Unix-like platforms only (Linux, macOS, BSD). tumbler reads a character-device entropy source and writes OSC 52 to /dev/tty; there is no Windows port.

Usage

tumbler [-n <words>] [-b <bits>] [-c <count>] [-d <device>] [-s <separator>] [-p] [-e] [--dice] [--no-capitalize]
Flag Default Description
-n, --words 6 Number of words (maximum 512)
-b, --bits — Target entropy in bits; computes word count automatically (overrides --words)
-c, --count 1 Number of passphrases to generate; above 1 implies --print
-d, --device /dev/urandom Entropy source device
-s, --separator "" Word separator
--dice — Use physical dice rolls as the entropy source
--no-capitalize — Do not capitalize words
-p, --print — Print to stdout instead of clipboard
-e, --entropy — Show entropy statistics

Examples

# Generate a 6-word passphrase and copy to clipboard (default)
tumbler

# Print instead of copying
tumbler --print

# Use a hardware TRNG directly
tumbler --device /dev/hwrng

# 8 words with hyphens, show entropy info
tumbler --words 8 --separator - --entropy --print
# 8 words × 12.925 bits/word = 103.4 bits  (wordlist: 7776 words)
# correct-horse-battery-staple-...

# 4 words for something you'll type frequently (still ~51 bits)
tumbler --words 4 --print

# The clipboard holds one value, so a count above 1 writes to stdout
tumbler --count 5

Security

Entropy

tumbler uses the EFF large wordlist (7776 words = 6⁵), giving 12.925 bits of entropy per word.

Words Bits Time to crack at 10¹² guesses/sec
4 51.7 ~42 days
5 64.6 ~660 years
6 77.5 ~6.4 million years
7 90.4 ~50 billion years
8 103.4 well beyond the heat death of the universe

6 words is the default and is appropriate for most purposes. Use 8 for high-value secrets or offline key material.

Bias elimination

Index selection uses rejection sampling over u64. The accepted range [0, threshold) is the largest multiple of the wordlist size that fits in 64 bits, ensuring every word is selected with exactly equal probability. The rejection probability for a 7776-word list is 2624/2⁶⁴ ≈ 1.4 × 10⁻¹⁶ — the loop body executes once in any practical scenario.

Entropy source

By default tumbler reads from /dev/urandom, which on Linux 5.6+ uses a BLAKE2s-based CSPRNG seeded from hardware entropy. This is cryptographically strong for all practical purposes.

If you have a hardware TRNG (e.g. an RDSEED-capable CPU, a dedicated USB device), you can pass its device path with --device /dev/hwrng. Note that raw hardware RNG output is unwhitened — a defective or biased device will produce biased passphrases. The kernel CSPRNG protects against this; bypass it only if you have a reason to.

Stuck source detection

Every 8-byte draw is compared against its predecessor. A device stuck at a constant value — the classic hardware failure mode — is rejected with an error rather than silently yielding the same word repeatedly. The rejection-sampling loop is likewise bounded, so a source that never produces an acceptable value fails fast instead of spinning. Two identical blocks from a working source have probability 2⁻⁶⁴.

This is a liveness check, not a randomness test. It catches a dead device; it cannot tell you a source is cryptographically strong. That remains the reason to prefer /dev/urandom.

Clipboard

tumbler uses OSC 52 to copy to the clipboard. The escape sequence is written directly to /dev/tty — no external tools required, no dependency on a display server, and it works transparently over SSH.

Supported terminal emulators include kitty, foot, WezTerm, xterm (with allowWindowOps), iTerm2, and tmux (with set-clipboard on).

A terminal never acknowledges OSC 52, so tumbler reports that it sent the copy sequence, not that the clipboard was set. On a terminal that ignores OSC 52 the passphrase goes nowhere — if tumbler reports success and your clipboard is unchanged, use --print.

If /dev/tty cannot be opened (fully non-interactive context), tumbler falls back to printing with a warning.

Memory hygiene

The passphrase is assembled in a single buffer that is zeroized on drop, as is the base64 clipboard payload. This limits how long the plaintext sits in the heap; it is not a defense against an attacker who can read the process's memory. Copies that leave tumbler's control are not covered: the stdout buffer under --print, the escape sequence once written to the tty, and anything the terminal or clipboard manager retains. There is no mlock, and core dumps are not disabled.

Building

Requires a Unix-like target; the build fails at compile time elsewhere.

cargo build --release

With Nix:

nix build

Disclaimer

This software is provided as-is with no warranty. Use at your own risk. It has not been audited by a security professional. Review the code before relying on it for anything sensitive.

License

MIT — see LICENSE.

About

A diceware passphrase generator with selectable entropy sources — copies high-entropy passphrases straight to your clipboard

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages