Dice Roll → BIP39 Verifier

SHA256-of-rolls method (Coldcard rolls.py / SeedSigner / Krux). This page runs the actual, verbatim source code of each project — the Python files execute in your browser via a locally bundled CPython/WebAssembly runtime (Pyodide). Nothing leaves this machine; all assets are local files.

Rolls → mnemonic

Type dice rolls as digits 1–6 (the field is prefilled with fresh random test rolls on every load — type or paste over them). Canonical lengths: 99 rolls for 24 words, 50 rolls for 12 words. The words are derived by six implementations: Coldcard's rolls.py (verbatim), the Coldcard firmware's own on-device dice code (v6.6.0X seed.py crypto core with the pure-Python bip39.py frozen into the firmware, run verbatim), SeedSigner's mnemonic_generation.py with the real embit 0.8.0 library (verbatim — also the exact encoding call Krux makes), Trezor's python-mnemonic (verbatim), iancoleman's jsbip39.js (verbatim JS), and Kern's dice_rolls.c logic with its pinned libwally-core (verbatim C sources compiled to WebAssembly). Five independent BIP39 encoders in total.

0 rolls
Loading Python runtime…

23 words → valid 24th words

Paste the first 23 words of a 24-word mnemonic; the 8 checksum-valid final words are listed.

Verbatim source versions

The Python columns execute these unmodified files (in web/py/); the iancoleman column executes the unmodified upstream JS (in web/js/); the Kern column executes the pinned C sources (reference/kern/, reference/libwally-core/, retrieved 2026-08-17) compiled to WebAssembly (web/kern/kern.wasm). All other files retrieved 2026-08-10; everything verified byte-identical to the latest release of each project. Only three kinds of glue are added, all non-cryptographic and clearly marked: import shims (web/py/seedsigner/, so SeedSigner's file can import outside its app; a 3-line jQuery stub for jsbip39's constructor), the string-marshalling wrapper compiled into the Kern wasm (web/kern/web_glue.c, plus linker stubs for elliptic-curve symbols the bip39 code never calls), and the wiring on this page.

ProjectLatest release (date)Verbatim file(s) @ commit
Coldcard rolls.pyv6.6.0X (2026-07-31)docs/rolls.py @ 05ac3893 (file last changed 2022-12-19) — Coinkite's official verification script, a standalone implementation separate from the firmware.
Coldcard firmware (on-device code)v6.6.0X (2026-07-31)shared/seed.py @ tag 2026-07-31T1609-v6.6.0X (8919b84a): the dice path is add_dice_rolls()sha256(b'') updated with each typed digit — then approve_word_list() truncates to 16 bytes for 12 words and calls bip39.b2a_words(). That bip39 module is pure Python, frozen into the firmware from libngu @ b0ce9acf (the release's submodule pin) — this page runs it byte-identical as web/py/bip39.py, with the seed.py crypto core extracted as coldcard_dice.py (device keypad/screen loop removed; reference/coldcard_seed_verbatim.py holds the untouched file). On-device the SHA256 primitive is MicroPython's uhashlib C module rather than CPython's — the cross-implementation agreement on this page is what covers that layer.
SeedSigner0.8.7 (2026-07-08)src/seedsigner/helpers/mnemonic_generation.py @ 0736e066
embit0.8.0 (PyPI sdist, 2024-05-30)complete package — SeedSigner's pinned dependency; runs its pure-Python backend in the browser
Kruxv26.08.0 (2026-08-04)no separate column: Krux D6 (dice_rolls.py @ bfbdaec5) computes the same digest and calls the same embit mnemonic_from_bytes as the SeedSigner column; its UI wrapper only runs on the device. Krux D20 joins rolls with "-" and will NOT match.
Kern0.0.16 (2026-08-11)C sources pinned @ 0.0.15 tag 5007930 (byte-identical at 0.0.16): dice_rolls.c (its crypto core extracted as reference/kern_dice.c, LVGL UI removed), bip39_filter.c (fully verbatim — the final-word checksum filter behind manual_input.c), compiled to web/kern/kern.wasm together with Kern's pinned libwally-core subset (odudex fork @ 47e75f96, verbatim — the wally_sha256 and bip39_mnemonic_from_bytes Kern calls). Built by web/kern/build_wasm.sh; tests/test_kern.py compiles the same sources natively and cross-checks them.
Trezor python-mnemonic0.21 (PyPI sdist, 2024-01-05)complete package (the BIP39 reference implementation)
iancoleman/bip390.5.6 (2023-08-01)jsbip39.js, sjcl-bip39.js, wordlist_english.js. Matches only when the SHA256 digest is pasted into the tool as raw hex entropy — its "Dice" mode uses base-6 conversion and will NOT match.
Pyodide runtime314.0.3 (npm)local copy in web/pyodide/; CPython compiled to WebAssembly
BIP39 wordlistbitcoin/bips bip-0039/english.txt @ ce1862ac, SHA256 2f5eed53…24dbda (used by the checksum panel; the columns use each project's own bundled wordlist)

Verify the sources yourself

Trust nothing this page claims — check it. Each SHA256 below is computed by your browser (WebCrypto) from the exact bytes this site served for that file. Run the copied command in a terminal to fetch the same file from the upstream project (pinned by commit hash or release tarball — a git commit is content-addressed, so its files can't change without changing the hash) and compare the two digests. A malicious copy of this page could of course fake this table too — which is why the commands fetch from upstream, not from here, and why verify_sources.sh in the repo performs the same byte-for-byte check for every vendored file without involving this page at all. This table lists the files that produce the words above; the page also executes the rest of the embit package and the Pyodide lockfile (byte-compared against upstream by verify_sources.sh) and two marked non-cryptographic shims (web/py/seedsigner/ — repo-authored, no upstream: verify_sources.sh and the test suite pin their hashes, and they are a few lines each, so read them). TRUST.md spells out the full model, including what this page can never prove.

File this page executedSHA256 of the served bytesUpstream