Mirror of github.com/intnsity/BigDice
  • Rust 93.7%
  • PowerShell 3.4%
  • Python 2.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-14 21:13:23 -06:00
.cargo BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
assets BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
docs BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
src BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
tests BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
tools BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
.gitattributes BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
.gitignore BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
build.rs BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
Cargo.lock BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
Cargo.toml BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
KEY.asc BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
LICENSE BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
LICENSE-fonts BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
README.md BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00
rust-toolchain.toml BigDice v0.3.0 - initial public release 2026-08-14 21:13:23 -06:00

BigDice

BigDice turns physical dice rolls into a Bitcoin seed phrase and the addresses that belong to it, on a computer that never touches a network. Your rolls are the only thing it builds a wallet from, and the same rolls always produce the same wallet, so anything it makes can be checked by doing it again.

The BigDice window with rolls entered

Contents

What BigDice does

You roll a handful of six-sided dice, type the results in, and BigDice shows you:

  • a BIP39 seed phrase - the 12 to 24 words a wallet is restored from;
  • the Bitcoin addresses that phrase produces, in all four common styles (BIP44, BIP49, BIP84, BIP86), with their private keys hidden until you ask for them.

It can also work the other way round: type in a seed phrase you already have and it shows you the wallet those words open. That is how you check that the words you wrote on paper last year are the right words.

There are two programs. They compute exactly the same values from the same input.

Program What it is Use it when
BigDice.exe A window with boxes and buttons. Normally. This is the one to use.
bigdice-cli.exe A text-only version that runs in a terminal. Scripting, or if the window will not start.

Each program is one file. There is no installer, nothing to configure, and nothing else to copy alongside it - the wordlist and the fonts are built into the file. What it needs is Windows 10 or later, and that is the whole list: not a graphics driver, not the Visual C++ redistributable, not an internet connection. Neither program opens a network connection or writes a settings file, and no key is ever derived from your computer's random number generator. Your dice are the randomness.

Four things worth knowing before you start.

  1. Whoever knows your rolls owns the wallet. The rolls are as secret as the words. Do not photograph them, email them, or leave them lying about.
  2. Write the first receive address on the paper next to the words. It is the only way to catch a word you copied down wrongly. Every check in this document comes back to it.
  3. Nothing is saved. Closing the window throws everything away. The words have to be on paper before you close it.
  4. Do not fund a wallet you have not checked. Restore the words into the wallet software you actually intend to use, and confirm it shows the same first address, before sending any coins.

Download and verify

A release is four files, downloaded from the Releases page:

File What it is
BigDice.exe The window.
bigdice-cli.exe The command-line version.
SHA256SUMS.txt A list of fingerprints, one line per file.
SHA256SUMS.txt.asc A GPG signature over that list.

A SHA-256 hash is a fingerprint of a file's exact contents. Change one byte anywhere in the file and the fingerprint changes completely, so comparing fingerprints tells you the file you have is the file that was published, and that it did not get damaged or altered on the way to you. The signature ties the list of fingerprints to this project's release key, so the list itself cannot be swapped out either.

First check the signature. You need GnuPG for this step:

  1. Download KEY.asc from the root of this repository and import it:

    gpg --import KEY.asc
    
  2. Check the fingerprint of the key you imported (gpg --fingerprint). It must be exactly:

    A1E9 53B2 5C6A 623B 77A1  D522 3AC4 BBCF E51A B37D
    

    That is an rsa4096 key. The same key is published on keys.openpgp.org, so you can fetch it from there instead and compare the two.

  3. Verify the signature on the list:

    gpg --verify SHA256SUMS.txt.asc SHA256SUMS.txt
    

    It must report a good signature from the key with that fingerprint.

Then check that the files you downloaded match the list:

  1. Put all four files in one folder.

  2. Open that folder, hold Shift, right-click the empty space, and choose Open PowerShell window here.

  3. Type this and press Enter:

    Get-FileHash .\BigDice.exe -Algorithm SHA256
    
  4. PowerShell prints a long line of letters and numbers. Open SHA256SUMS.txt in Notepad, find the line that names BigDice.exe, and compare the two values. They must be identical. Upper and lower case do not matter; nothing else may differ.

  5. Do the same for bigdice-cli.exe.

If a value does not match, delete the file and download it again. Do not run it.

No fingerprint is printed in this document, deliberately. This file is one of the inputs the programs are built from, so any hash written here would describe a build other than the one it ships with, and would be wrong the moment it was saved. The fingerprints are in SHA256SUMS.txt attached to the GitHub release, signed with the key in KEY.asc; the list is written after the final build and is not an input to it.

The "Source code (zip / tar.gz)" archives on the release page are generated by GitHub and are not covered by SHA256SUMS.txt. To verify the source itself, clone the repository, run git verify-tag v0.3.0, and build from that signed tag.

Using the app

Double-click BigDice.exe. It opens straight away; nothing is installed and nothing is written to your disk.

The window has a left column where you type, a right column that shows results, and a MAINNET or TESTNET badge in the top bar so you always know which network you are looking at. The right column updates about a quarter of a second after you stop typing.

Every picture here was taken from the current 0.3.0 window, with the rolls and the phrase that docs/screenshots/README.md records. Both are published in this repository, so the wallets on screen are public ones: safe to look at, never to be funded.

1. Type your rolls

Make sure the Dice rolls tab is selected, then roll a die and type the number. Roll again, type again. Keep going.

Only the digits 1 to 6 count. Spaces, commas and line breaks are ignored, so group them however you find easiest to check - 123456 234561 345612 is exactly the same input as 123456234561345612. Any other character is thrown away, and the Entropy card below tells you how many characters it ignored, so a stray letter cannot change your wallet without you seeing it.

Clear all empties the box.

2. Watch the strength meter

The Entropy card counts the rolls it accepted and shows a meter with three bands:

Band Meaning
weak Under 128 bits. Not enough. Keep rolling.
ok 128 to 255 bits. This is the normal target.
strong 256 bits or more.

The meter measures the dice, not the words. Asking for more words does not move it - see How many dice rolls.

3. Choose how many words

The Mnemonic length card offers Raw (use all my dice) or a fixed 12, 15, 18, 21 or 24 words.

  • Raw uses every bit your dice actually produced. More rolls means more words. This is the honest option and the default.
  • A fixed count always gives you exactly that many words, whatever you rolled. It does not add strength. Twelve words made from six rolls are still only as strong as six rolls, and the app says so in red when that happens.

Pick Raw unless some other piece of software insists on a particular word count.

4. The passphrase checkbox

Leave this off unless you know you want it. It is off when the window opens.

Use passphrase (25th word) adds an extra secret of your own on top of the dice. It is not a password that protects the wallet - it selects a different wallet. The same words with the passphrase dog and the same words with the passphrase Dog are two completely unrelated wallets, and nothing anywhere records which one you used.

The passphrase card with a passphrase in force

If you turn it on:

  • You type it twice, and the results on the right do not move until the two entries match.
  • A PASSPHRASE ACTIVE badge appears, so a run with a passphrase never looks like a run without one.
  • A typo in it cannot be detected, ever. The words have a built-in checksum; a passphrase has none. A trailing space or a capital letter gives you a perfectly valid wallet that simply is not yours, with no error message.
  • You must write it down, exactly, alongside the words. Forgetting it loses the coins as completely as losing the words.
  • The card shows a character count and a byte count. Some hardware wallets refuse passphrases longer than 50 bytes; if your wallet must be restorable on a device, check that device's limit first.

Turning the checkbox off again wipes what you typed.

5. Write down the words and the first address

The right column shows the seed phrase as a numbered grid, with a Copy words button. The words start hidden, like every other private value - see Showing private keys for how to put them on screen when you are ready to write them down.

Below it are the four address styles as tabs - BIP44, BIP49, BIP84, BIP86. BIP84 is the modern default (addresses starting bc1q); use it unless you have a reason not to. Each tab lists addresses with their paths.

The address table with a row hovered

Write on paper, by hand:

  • the words, in order, in lower case;
  • the first address of the tab you will use (m/84'/0'/0'/0/0 on the BIP84 tab);
  • whether you used a passphrase, and what it was.

Then verify by repetition: clear the box, type the same rolls in a second time, and confirm you get the same words and the same first address.

There is also a Safety card at the bottom of the results, collapsed, which repeats the short version of all of this.

The Safety card expanded

6. Checking a phrase you already have

Switch the left column to the Mnemonic tab and type in words you already have. No dice are involved and nothing is generated - it simply shows you the wallet those exact words open.

The Mnemonic tab with a phrase typed in

This is what closes the loop on step 5. Take the paper, type the words back in, and check that the first address matches the one written beside them. That is the one check that catches a word copied down wrongly, and it is worth doing before you fund anything and again before you rely on the backup.

The card underneath reports what it found:

Badge What it means
CHECKSUM VALID The words are consistent. They are a phrase some tool really did produce.
CHECKSUM INVALID Every word is a real BIP39 word, but they do not add up - usually one word mistyped or two swapped.
CHECKSUM NOT APPLICABLE At least one word is not in the BIP39 list, so the check cannot be made. Unknown words are listed by name.

None of these stop it. BigDice still shows you the wallet the text produces, because the whole point of this mode is to find out what a phrase does, including a phrase you think you mistyped. A warning appears beside the result rather than in place of it.

Two things to watch:

  • Case matters for the wallet, though not for the spelling check. Hat and hat are the same word to the checksum and different wallets to the seed. Write words in lower case.
  • A wrong passphrase looks like a right one. A matching checksum and a wrong address means the passphrase, or the capitalisation, not the words.

7. QR codes

Nothing on screen is a QR code until you ask for one. Values worth scanning have a QR button beside their copy button; clicking it opens one code on its own, and dismissing it puts it away.

An address shown as a QR code

A QR code of a secret is exactly as dangerous as the secret and much easier to lose - a camera across the room, a screenshot or a screen-sharing window captures it whole in one frame, where the text form would have to be transcribed by hand. So the QR button on any private value is locked behind the same confirmation as the value itself, including the seed phrase.

Public codes (an address, an account xpub) are safe to scan in the sense that they cannot spend anything, but they do reveal which addresses are yours. The genuinely useful one is the account public key: scanning it into a watch-only wallet on your everyday computer lets that computer show your balance without ever seeing a private key.

8. Showing private keys

Private values - the seed words, the entropy hex, the private key column, the seed, the root key - are drawn as a fixed row of dots. Always the same number of dots, so the masking does not even leak how long the secret is. The words keep their numbered grid while hidden, one mask per slot, so nothing on the page moves when you reveal them.

The words are covered because they are the wallet: everything else on that screen is derived from them, and a switch called Hide private keys that left them readable would be hiding the copies and printing the original. What you type yourself on the Mnemonic tab is not masked - it is your own input, and you have to be able to proof-read it.

The confirmation asked for before private keys are shown

Unchecking Hide private keys does not reveal them. The checkbox springs back and a dialog explains what is about to appear on screen; you have to confirm. That is one confirmation for the whole screen - words, entropy, seed, root key and every WIF appear together. Pressing Escape or clicking outside cancels, so the safe answer is whatever you get by dismissing it, and the answer is not remembered the next time you open the app.

You do not need the private keys. The words are the backup. The keys are there for the rare case where some other tool asks for one.

One more thing about copying: the status bar has an Auto-clear checkbox that wipes the Windows clipboard 90 seconds after BigDice put something in it. Windows Clipboard History (Win+V), if you have it on, keeps its own copy that no program can erase - turn it off before copying any key.

How many dice rolls

Roll more than you think you need. It costs nothing but time, and it cannot be fixed later: the strength of a wallet is fixed at the moment it is created.

What you want Roll about Easy number to aim for You will get
The normal standard (128 bits) 77 rolls 100 12 words or more
The paranoid standard (256 bits) 154 rolls 200 24 words or more, commonly 30

Anything above those numbers is fine. Below 128 bits BigDice warns you, in both programs and on the meter.

Why the numbers are not round: a die does not give a whole number of bits. Rolls of 4 and 5 contribute one bit each and rolls of 1, 2, 3 and 6 contribute two, which averages out to about 1.67 bits per roll, so the exact total depends on what you actually rolled. This is the same encoding the iancoleman/bip39 page uses, which is why the same rolls give the same wallet in both.

Use ordinary dice and roll them properly. Casino dice are better than cheap moulded ones, but any die that is not obviously loaded is fine, and rolling a hundred times beats agonising over the dice.

The command line

Optional. Skip this section unless you want to script BigDice or the window will not start. bigdice-cli.exe computes exactly the same values as the window.

The safest way to use it is to run it with no arguments at all and type the rolls when it asks - they never appear in your command history and never touch the disk:

> bigdice-cli --scheme bip84 --count 2
bigdice-cli 0.3.0
Offline BIP39 from dice. The rolls you type are the only entropy used.

Enter dice rolls (1-6). Anything else is ignored, so spaces and commas are fine.
Roll at least 77 dice for 128 bits, 154 for 256. The count in the prompt is how many have been accepted.
Finish with a line containing only ".", or with end of input.
rolls[0]> 1234 5612 3456 1234
rolls[16]> 5612 3456 1234 5612
rolls[32]> .
Accepted 32 dice rolls.
Use a BIP39 passphrase? [y/N] n
Word count (raw, 12, 15, 18, 21, 24) [raw]: 12

The number in each prompt is how many rolls have been accepted so far. Finish with a line containing only a full stop - a blank line does not end entry, because a pasted dice log usually contains one. The report is printed underneath. Those 32 rolls are a short example, not a recommendation: they are 54 bits, well under the minimum, and the report carries two warnings saying so above the words.

When the console window belongs to the program - which is what double-clicking bigdice-cli.exe gives you - the session ends with Press Enter to close this window. and waits, so the report can be read and copied before the window goes. A terminal you opened yourself is not held open, because it outlives the program anyway, and neither is --json or output redirected to a file.

Options

All flags are long form. Both --flag value and --flag=value work. Scalar flags take the last value given; --dice and --dice-file accumulate in command-line order.

Flag Values Default Notes
--dice <rolls> any string - Every character outside 1-6 is ignored. Repeatable. Leaves the rolls in shell history.
--dice-file <path> path - Repeatable, combinable with --dice.
--mnemonic <phrase> any string - Derive from a phrase you already have instead of dice. Excludes the dice flags and --mnemonic-file. Leaves the phrase in shell history.
--mnemonic-file <path> path, or - for stdin - The same phrase from a file, or the whole of stdin. Must be valid UTF-8; nothing is trimmed. Excludes --mnemonic.
--words <mode> raw, 12, 15, 18, 21, 24 raw Dice input only. raw uses the dice bits themselves and can exceed 24 words. A fixed count hashes the digit string.
--passphrase-prompt - off Hidden entry, typed twice, must match.
--passphrase-file <path> path, or - for stdin - The file's whole content minus one trailing line ending. Excludes --passphrase-prompt.
--scheme <list> comma list of bip44, bip48, bip49, bip84, bip86, all all Which schemes the report derives. all expands to the four single-signature schemes. bip48 derives multisig account keys only, with no address rows, and is never part of all - ask for it by name, alone or in a list (all,bip48 is the full set the window derives).
--script-type <n> 0, 1, 2 2 BIP48 only: the hardened script-type level in the path. 0 is P2SH, 1 is P2WSH, 2 is P2SH-P2WSH.
--account <n> 0 .. 2147483647 0 Hardened account index.
--change <n> 0 .. 2147483647 0 0 is the external chain, 1 the internal one.
--count <n> 0 .. 10000 20 Address rows per scheme. 0 prints the account keys only.
--network <name> mainnet (or bitcoin), testnet mainnet Testnet uses coin type 1 and tprv/tpub, with no SLIP-132 rendering.
--json - off One JSON object on stdout instead of the human report.
--qr <target> root, <scheme>:pub, <scheme>:slip132, <scheme>:<row> - Draw one QR symbol after the report. Excludes --json.
--help - - -h, -?, /? and help work too.
--version - - Version and source id.

With no input flag at all the rolls are read from the terminal, and every other flag still applies.

Every report also prints the BIP32 master fingerprint - the first four bytes of HASH160 of the master public key - on the Fingerprint line under Seed and root key. It is a public identifier, not a secret; multisig coordinators ask for it alongside the account xpub, which is what --scheme bip48 produces.

Exit codes: 0 success, 1 internal failure, 2 usage error. Error text goes to stderr.

Examples

bigdice-cli --dice-file rolls.txt --words 24 --scheme bip84
bigdice-cli --dice-file rolls.txt --network testnet --scheme bip86 --account 1 --change 1
bigdice-cli --passphrase-prompt --count 5
bigdice-cli --mnemonic-file phrase.txt --scheme bip84 --count 1
bigdice-cli --dice-file rolls.txt --scheme bip84 --count 1 --json
bigdice-cli --dice-file rolls.txt --scheme bip84 --count 1 --qr bip84:0

--dice "..." works too, but it writes your rolls into your shell's history file, where they stay. Prefer typing them at the prompt or passing a file you then destroy.

Checking a phrase from the command line

--mnemonic is the terminal version of the window's Mnemonic tab:

> bigdice-cli --mnemonic "refuse hand spider pet egg misery brave custom home surface refuse hat" --scheme bip84 --count 2
Mnemonic input
  Word count    : 12
  Unknown words : (none)
  Checksum      : valid
  Passphrase    : (none)
  Mnemonic      :
    refuse hand spider pet egg misery brave custom home surface refuse hat

The report continues with the seed, the root key and the addresses, exactly as a dice run does. A bad checksum or an unknown word is a warning printed beside the result, not a refusal.

QR codes from the command line

--qr <target> draws one code after the report, for the one value you name: root for the root key, bip84:pub for an account public key, bip84:slip132 for the same key in zpub form, or bip84:0 for the first address in that table. It cannot be combined with --json. The value is printed as text above the code, so what was encoded can be read as well as scanned.

Note about terminals: the drawing uses block characters, and a terminal paints blocks in its text colour. The code therefore scans correctly on a dark background and comes out inverted on a light one. If your scanner sees nothing, invert your terminal colours for the moment of the scan, or use the window, which always paints codes dark on white.

Passphrases from the command line

No flag takes a passphrase as a value on the command line, because a command line is readable by every process running as you and PowerShell records it to a history file. Use either:

  • --passphrase-prompt, which asks twice with the typing hidden and requires the two to match; or
  • --passphrase-file <path>, which reads it from a file.

The file rules are strict on purpose, because every one of them is the difference between two wallets: exactly one trailing line ending is removed and nothing else is trimmed, a leading byte order mark is refused (PowerShell's Out-File and Set-Content write one by default), invalid UTF-8 is refused, and an empty file is refused rather than quietly giving you the no-passphrase wallet. Delete the file afterwards.

Moving it to an offline computer

The whole point of BigDice is to run it on a computer with no network connection. Nothing about getting it there is difficult.

  1. On your normal computer, download the release and check the hashes as described in Download and verify.

  2. Write the fingerprint down on paper, or take a photo of the screen:

    > Get-FileHash .\BigDice.exe -Algorithm SHA256
    
  3. Copy the program to a USB stick. Just the .exe - there is nothing else to bring.

  4. On the offline computer, check the fingerprint again before running it:

    > Get-FileHash D:\BigDice.exe -Algorithm SHA256
    

    It must match what you wrote down. A mismatch means the file changed on the way; do not run it.

  5. Roll dice and use the app. Write the words on paper along with the first receive address, as described in Write down the words and the first address.

  6. Check the paper, not the screen. Type the words back from your paper into the Mnemonic tab and confirm the first address matches the one you wrote beside them. This is the step that catches a mis-copied word, and it is the only one that does.

  7. Leave nothing behind. The window writes no files, so switching the machine off is the whole of the cleanup. If you used --dice-file, --mnemonic-file or --passphrase-file, destroy those files and the stick they lived on.

The one thing worth carrying back to your everyday computer is the account public key (xpub / zpub). Loading it into a watch-only wallet lets that computer show your balance and generate receiving addresses, and confirms both machines agree about the wallet, without any private key ever leaving the offline one.

Troubleshooting

The computer has no graphics driver, or the window feels slow. The window opens anyway. It renders through Direct3D 12, and when a machine has no display driver at all - the normal state of a freshly installed offline PC - Windows supplies WARP, the software renderer built into Windows 10 and later. Nothing has to be installed beside the executable. The cost is speed: software rendering redraws the window far more slowly than a GPU does, so scrolling and dragging can feel laggy, and a smaller window is noticeably faster than a large one. Only the drawing is slow; everything BigDice computes is as fast as ever. If it bothers you, use bigdice-cli.exe instead, which needs no graphics at all.

BigDice.exe does not open at all. That is unusual now, since the renderer above needs no driver. It leaves a file called BigDice_error.txt in the folder it was run from, explaining what failed. Use bigdice-cli.exe; it computes exactly the same values.

I double-clicked bigdice-cli.exe and the window vanished. It no longer does: a session at a console the program owns ends with Press Enter to close this window. and waits. See The command line for which runs are held open and which are not.

The passphrase prompt fails in Git Bash with "The handle is invalid". Hidden passphrase entry needs a real Windows console, and Git Bash's MinTTY window does not provide one. Run bigdice-cli.exe from PowerShell or cmd.exe instead. The error message says as much.

Related: piping text into the program under Windows PowerShell 5.1 does not work as you would expect. PowerShell inserts an invisible marker byte at the front of anything it pipes into a program, which becomes part of the passphrase or phrase. BigDice deliberately does not strip it - a silently altered phrase is a wallet nobody can find again - so it reports an unknown first word or a mismatched passphrase instead. Pass a file rather than a pipe.

error: no dice rolls in the input. Every character outside 1 to 6 is thrown away, so this means nothing usable reached the program - usually the quoting of --dice, or the wrong path in --dice-file.

error: not enough dice entropy. Keep rolling. The message says how many more rolls are typically needed.

The words look right but the address is wrong. Check the passphrase first, then the capitalisation of the words, then the scheme tab you are comparing against (BIP44, 49, 84 and 86 all give different, equally valid addresses for the same phrase).

Building from source

You need Rust 1.85 or newer. From the crate directory:

cargo build --release                                                     # bigdice-cli.exe
cargo build --release --no-default-features --features gui --bin BigDice  # BigDice.exe

Run cargo from the crate directory: .cargo/config.toml there asks for a statically linked C runtime, which is what lets the executables start on a Windows machine with no Visual C++ redistributable installed, and cargo reads that file from the directory you invoke it in. A release build that loses the flag refuses to compile rather than producing an executable that fails on the target machine.

The published binaries are built with --locked, with the toolchain pinned by rust-toolchain.toml, with the cargo home remapped so that no path from the build machine is embedded in dependency panic messages, and with /Brepro, which replaces the link timestamp the PE header would otherwise carry with a hash of the content - without it two otherwise identical builds differ in a few header bytes. To reproduce them byte for byte, build from the signed tag with:

$env:RUSTFLAGS = "-C target-feature=+crt-static --remap-path-prefix=$env:USERPROFILE\.cargo=/cargo -C link-arg=/Brepro"
cargo build --release --locked                                                     # bigdice-cli.exe
cargo build --release --locked --no-default-features --features gui --bin BigDice  # BigDice.exe

(Setting RUSTFLAGS replaces the flags from .cargo/config.toml, so the static-CRT flag is repeated there. If your cargo home is not %USERPROFILE%\.cargo, remap the path cargo --version --verbose reports as its home instead.)

The GUI build turns the default cli feature off as well as turning gui on. That is deliberate: it keeps the terminal passphrase reader, and its dependencies, out of a binary that can never call it.

To run the tests:

cargo test

163 pass and 1 is ignored on purpose - it records a laxness in a dependency's key parser that this crate cannot reach, and is there to be un-ignored the day it can. The two front ends are checked against each other separately, because that takes both executables:

powershell -ExecutionPolicy Bypass -File tools\verify.ps1

That runs 24 cases through bigdice-cli --json and BigDice --selftest and compares the two documents byte for byte.

To publish a build, write the fingerprints of the two executables:

Get-FileHash BigDice.exe, bigdice-cli.exe -Algorithm SHA256 |
  ForEach-Object { "{0}  {1}" -f $_.Hash.ToLower(), (Split-Path $_.Path -Leaf) }

Save that as SHA256SUMS.txt, sign it with a detached GPG signature (gpg --detach-sign --armor SHA256SUMS.txt produces SHA256SUMS.txt.asc), and attach all four files to the GitHub Release. The manifest is written after the final build and is not an input to it, which is what makes it safe to publish: hashing a file that goes back into the build would change what it describes.

Version history and rollback

0.3.0 (current) adds BIP48 multisig account key derivation (--scheme bip48 with --script-type, and the window's BIP48 tab) and puts the BIP32 master fingerprint in the report and on screen - the two things a multisig coordinator asks for. It also brings security hardening, including to the release process itself: the hash manifest is now signed, as described in Download and verify. The four single-signature schemes derive exactly what 0.2.1 derived.

0.2.1 is a display-only change to the window: Hide private keys now covers the seed words and the entropy hex as well, instead of leaving the two secrets everything else is derived from in plain text. No key derivation changed, and the machine-readable output of both programs is byte for byte what 0.2.0 produced.

0.2.0 added two things: reading back a seed phrase you already have (--mnemonic, --mnemonic-file, and the window's Mnemonic tab) and QR codes (--qr, and the window's QR buttons). The dice path was not touched, and there is a test that proves it: a dice run's machine-readable output is compared byte for byte against output captured from the released 0.1.0 executable, and must be identical. The window also changed how it draws - Direct3D 12 instead of OpenGL - which is what removed the graphics-driver requirement, at the cost of about 4 MB of executable.

0.1.0 was the first release.

Versions before 0.3.0 predate this repository's public history. To roll back, download and verify the previous signed release from the Releases page rather than checking out an old tag. --version prints the version together with a source id - a fingerprint of the exact sources the program was built from - so a binary of unknown age can be asked what it is:

> bigdice-cli --version
bigdice-cli 0.3.0 source <16 hex digits>

Two programs printing the same source id were built from byte-identical sources, dependency versions included.

For the technically curious

BigDice is checked three ways, and all three are in this repository. It reproduces the official test vectors published with the BIP standards themselves (BIP32, BIP39, BIP49, BIP84, BIP86 and SLIP-132), including the Japanese cases that exercise Unicode normalization. It reproduces the output of the iancoleman/bip39 standalone page it is modelled on, captured from a real run of the real page and compared field by field. And it reproduces two independent implementations that share no code with it or with each other - iancoleman's own JavaScript run under node, and the Python bip-utils library - across a differential fuzz run of 224 cases and 17890 fields with zero mismatches.

Where to read further:

Document What it covers
docs/SPEC.md The normative algorithm, step by step. The code cites it as "SPEC step N".
docs/EQUIVALENCE.md Why independently written code reproduces the iancoleman page, and the evidence that it does.
docs/LINEAGE.md An independent code-provenance and supply-chain audit of this crate.
docs/REFERENCE.md The complete reference manual: every flag, every output field, the JSON contract, memory hygiene, and the full verification story.
tests/vectors/README.md Where each test vector came from.
docs/screenshots/README.md Which binary and which rolls produced each picture.

The short version of the security model: key derivation uses no operating-system randomness and no clock, neither program opens a socket, and both facts are enforced by tests that walk the dependency graph and fail if an RNG or networking crate appears in it. Every secret - the rolls, the passphrase, the seed, the phrase and the private keys - is wiped from memory when it is dropped. What no program can prevent from inside is Windows writing memory to pagefile.sys, or keeping your command line where another process can read it, which is why typing rolls at the prompt is preferred over passing them as arguments.

License

The code is licensed under GPL-3.0-or-later; see LICENSE. The embedded fonts are licensed separately, as described in LICENSE-fonts: the subsets in assets/ are under the SIL Open Font License, and the GUI framework bundles its own fallback faces under their respective licenses.

Donations

BigDice is free software; nothing in it asks for payment. If it was useful and you want to pay something forward, consider donating to OpenSats, a 501(c)(3) public charity that funds open-source bitcoin development: https://opensats.org/donate#give-once