Skip to content
BestBitcoinDice
menu

18+ · Gambling involves risk · Not for US or UK playersAffiliate disclosureGet help

Provably Fair Dice: Verify Every Roll Yourself

How provably fair Bitcoin dice works: server seed hash, client seed, nonce and HMAC-SHA256, with a new worked example and Python code to check each roll.

By Best Bitcoin Dice Editorial TeamUpdated 10 min read50 claims checked 7 Oct 2026

Provably fair dice lets you prove, after the fact, that a crypto casino fixed each roll before you bet. The site locks in a secret server seed by showing you its SHA-256 hash, you add a client seed of your own, and every roll is calculated from both plus a bet counter called the nonce. Once the seed is revealed you can rerun the maths on your own computer and match every result in your history.

Below we do exactly that with a brand-new seed pair we generated for this page: six rolls, a short Python script that reproduces them, a tampering test, and a 100,000-roll sanity check. Then we cover the part most guides skip: what a successful check does not tell you about a dice casino.

How the commit-and-reveal scheme works

Think of it as a sealed envelope. Before you place a bet, the casino writes its secret on a card, seals it, and hands you the envelope’s fingerprint. You cannot read the card, and the casino cannot swap it without the fingerprint changing. After your session you ask for the envelope to be opened and check that the card matches.

In practice the “card” is a 64-character hexadecimal server seed and the “fingerprint” is its SHA-256 hash. SHA-256 is a one-way function standardised by NIST in FIPS 180-4: the same input always produces the same 64-character output, and nobody can run it backwards to find the seed. Your client seed is the extra ingredient. Because you set it after the hash was published, the casino could not have picked a server seed that produces bad rolls for your particular client seed.

Stake publishes its full method, and most in-house crypto dice games follow the same pattern. We use that documented method throughout this guide because it can be checked line by line against the operator’s own pages.

Verify a revealed roll

Paste the values from a finished, rotated seed pair. The check runs in your browser with Web Crypto; nothing is sent anywhere. The adapter follows Stake's published dice formula. The values filled in below are a fictional demonstration, not an operator result.

1 · Commitment

Match: SHA-256 of the revealed seed equals the commitment.

e32a467269ebc16494c85d8131f055dcd8436ef6687bc6053f079f6fe842a928

2 · HMAC-SHA256(server seed, "client:nonce:0")

343590413f23288e443070bfd21be12a5d4f127b28cddc7bb287c6126518ea54

3 · First 4 bytes as a fraction

0.2039423140
4 · Roll = floor(fraction × 10,001) ÷ 10020.39

What a match does not prove

  • that the site holds a valid licence or will pay a withdrawal;
  • that dice is legal where you live;
  • that the game has no house edge: it proves the roll, and the edge is in the payout.

The inputs at a glance

Input Who controls it Visible to you Role in the roll
Server seed Casino Only after you rotate to a new pair Secret key for the HMAC function
Hashed server seed Casino (derived) Before your first bet The commitment you check later
Client seed You (a default is set for you) Always Part of the message being hashed
Nonce Counts automatically In each bet’s details Makes every bet on the same pair different
Cursor Fixed by the game Rarely shown Stays 0 for dice, which needs only one number per roll

Stake’s implementation page lists dice among the games that use a single cursor value (0), because one hash gives 32 bytes and a dice roll needs only four of them.

A full verification, roll by roll

Every value in this section was generated by us for this page and has never been used at a casino. You can reproduce all of it.

Item Value
Server seed (revealed after rotation) 9c3e5a17b2d84f60e1a7c4b958d2f03a6e8b1d47c5a9f2e03b6d8c1a4e7f9b25
Hash shown before betting f836a5d3fd7c1de9709e7656aa59bc74b0b7fa0bfae8b2a58a8bf5ff12c4f4a3
Client seed dice-night-0710
Nonces checked 0 to 5
Bet on every roll 0.0001 BTC, roll over 66.00 (34% win chance)

Step 1: confirm the commitment

Hash the revealed seed with SHA-256, treating the 64 characters as ordinary text. Our result starts f836a5d3 and ends 12c4f4a3, identical to the hash shown before the first bet. That single match proves the casino used this seed for the whole session.

Step 2: rebuild the HMAC for nonce 0

HMAC-SHA256 (defined in RFC 2104) takes a key and a message. The key is the server seed; the message is the client seed, the nonce and the cursor joined by colons: dice-night-0710:0:0. The 32-byte output begins 08 c3 c5 06 in hexadecimal.

Step 3: four bytes become a fraction

Those bytes are 8, 195, 197 and 6 in decimal. Read as one 32-bit number and divided by 2 to the power 32, they give the same value as dividing each byte by a growing power of 256 and adding the parts: 8/256 + 195/65,536 + 197/16,777,216 + 6/4,294,967,296 = 0.03423721. Using four bytes instead of one gives the fraction enough precision for a two-decimal roll.

Step 4: the fraction becomes a roll

Stake’s dice range runs from 0.00 to 100.00, which is 10,001 possible results. The documented conversion multiplies the fraction by 10,001 and divides by 100: 0.03423721 x 10,001 / 100 = 3.424. The game displays 3.42.

Step 5: settle the bet

Our bet needed a roll above 66.00, so nonce 0 lost. Repeating steps 2 to 4 for the next five nonces gives the full history:

Nonce HMAC output (first 8 hex) Fraction Roll Over 66.00?
0 08c3c506 0.03423721 3.42 Lose
1 d5e79dff 0.83556545 83.56 Win
2 ab485991 0.66907272 66.91 Win
3 65f7e88f 0.39831403 39.83 Lose
4 b301e915 0.69924790 69.93 Win
5 9ece1568 0.62033209 62.03 Lose

At a 1% house edge, a 34% chance pays 99 / 34 = 2.9118x. Three wins returned 3 x 0.00029118 = 0.00087354 BTC against 0.0006 BTC staked, a profit of 0.00027354 BTC. Six rolls prove nothing about luck, of course; they only prove these six results were fixed in advance.

Run the check yourself in Python

Python 3 ships with the two modules you need. Paste these lines into a Python prompt (the last line is one long statement):

import hmac, hashlib
seed = ‘9c3e5a17b2d84f60e1a7c4b958d2f03a6e8b1d47c5a9f2e03b6d8c1a4e7f9b25’
print(hashlib.sha256(seed.encode()).hexdigest())
msgs = [f’dice-night-0710:{n}:0′ for n in range(6)]
for m in msgs: b = hmac.new(seed.encode(), m.encode(), hashlib.sha256).digest(); f = int.from_bytes(b[:4], ‘big’) / 2 ** 32; print(m, b.hex()[:8], round(f, 8), int(f * 10001) / 100)

The output is the hash from step 1 followed by six lines that match the table. To check your own bets, replace the seed, the client seed and the nonce range with the values from your casino’s fairness panel and bet history.

Two experiments that show why it works

Change one character of the server seed

Suppose a dishonest operator swapped the last character of our seed from 5 to 6 after seeing your bets. The hash of the altered seed is a06790720bcabb48f1c9d8d0b5728adf347624a1b2d45014fc84477f50d4d2ae, which shares nothing recognisable with the f836a5d3 hash you were shown. Any swap, however small, fails step 1 at once.

Change your client seed

Keep the same server seed but set the client seed to dice-night-0711, one digit different. Nonces 0, 1 and 2 now roll 82.04, 89.64 and 93.00 instead of 3.42, 83.56 and 66.91. Because the casino committed to its seed before knowing your input, it had no way to steer the rolls you would get. This is why changing the default client seed at least once is worth the ten seconds it takes.

100,000 rolls from a single seed pair

A fair conversion should spread rolls evenly across the range. We ran nonces 0 to 99,999 through the same script:

Measure Expected Our 100,000 rolls
Average roll 50.00 49.91
Share below 50.00 49.995% (5,000 of 10,001 values) 50.165%
Share above 66.00 33.997% (3,400 of 10,001 values) 33.845%
Lowest and highest roll 0.00 and 100.00 0.00 and 100.00

Every gap is within the normal noise for a sample of this size (one standard deviation on a 34% share is about 0.15 percentage points). A test like this cannot prove a casino is honest, since it uses our seeds rather than theirs, but it shows that the published formula itself produces evenly spread rolls.

Where the house edge lives

Notice that nothing in the roll calculation favours the casino. The edge sits in the payout. A fair game would pay 100 / 34 = 2.9412x for a 34% chance; Stake pays 99 / 34 = 2.9118x, and that 1% difference is its cut on every bet. Stake lists its dice payouts from 1.0102x to 9,900x and states a 99% RTP on the game page.

Other games set the payout factor differently. BetFury lists an RTP of 99.02% for its Dice, paying 1.9804x on a 50% chance, while Spribe’s provider Dice, found at many casinos, is listed at 97%. A provably fair check confirms the roll; it is the payout table that tells you the price. Our guide to playing dice shows the formula for every target.

What a passed check does not prove

  • The house edge. A perfectly verifiable game can still charge 3% or more. Compare the multiplier with 100 divided by your win chance.
  • That you will be paid. Provably fair covers the result, not withdrawals, limits or account closures. Those depend on the operator’s terms and licence.
  • Third-party games. Most slots and live tables come from studios that use lab-tested RNGs instead of seeds, so there is nothing for you to verify.
  • The current session. You can only check a seed after rotating it. Until then the hash is a promise, not proof.
  • A neutral verifier. A verification page hosted by the casino runs the casino’s code. Use your own script or an open-source tool for the final check.

Choosing a dice casino: fairness is one line of the checklist

The older pages this guide replaces promised “no registration”, total anonymity, “no country restrictions” and instant payouts. That picture is out of date. Licensed crypto casinos publish restricted-country lists, ask for identity documents (KYC) under their anti-money-laundering rules, especially before large withdrawals, and can void winnings won from a blocked country. Before you deposit, check:

  1. Licence and operator. Stake’s licence, OGL/2024/1451/0918, was issued by the Curaçao Gaming Authority to Medium Rare N.V.; BC.Game and FortuneJack hold Anjouan licences, which you check through the seal on each site.
  2. Your country. Read the restricted list in the terms. US and UK residents are on the blocked lists of Stake, BC.Game and FortuneJack alike.
  3. Published edge. The multiplier for a 50% chance tells you the edge instantly: 1.98x means 1%, 1.96x means 2%.
  4. Seed controls. You should be able to see the hashed seed, edit the client seed and rotate the pair whenever you like.
  5. Bonus terms. Many welcome offers exclude dice or count it at a reduced rate towards wagering.
  6. Responsible gambling tools. Deposit limits, cool-off and self-exclusion should be one click away. Our safer gambling page lists help services.

Separate reviews of Stake, BC.Game, FortuneJack and BetFury go through these points one site at a time, and the Bitcoin dice site comparison puts them side by side.

Five mistakes that make a fair roll look unfair

  • Off-by-one nonce. Our example starts at 0. If your first bet shows nonce 1 in the history, start there.
  • Hidden spaces. A trailing space in a copied client seed changes every result.
  • Hashing the seed as bytes. Stake-style checks hash the seed as text. Decoding the hex into raw bytes first gives a different hash.
  • Rounding instead of cutting. The game drops digits beyond two decimals. A roll of 66.996 shows as 66.99, not 67.00, which matters right at your target.
  • Using another site’s formula. Conversions differ between casinos. Use the formula the operator documents for that exact game.

If a result still does not match after these checks, save the seeds, nonces and bet IDs and raise it with the casino’s support team first, then with the complaint route its licence provides. Keep stakes at a level where a dispute would be an annoyance rather than a crisis, and see our honest look at dice strategy for why no system changes the edge.

Provably fair dice: reader questions

Is provably fair dice actually fair?

It proves each roll was fixed before you bet and was not changed afterwards. It does not make the game free: the casino still keeps an edge through the payout, 1% on Stake Dice and 3% on Spribe’s Dice.

How do I verify a dice roll I already played?

Switch to a fresh seed pair, which makes the casino publish the previous server seed. Run SHA-256 on that seed and compare the output with the commitment hash, then feed client seed:nonce:0 into HMAC-SHA256 keyed with that seed, turn the first four bytes into a fraction and apply the game’s conversion.

Why can’t I check my current server seed?

Revealing the active seed would let you calculate every future roll in advance. You only get it once you switch to a new pair, after which the old one can be checked against its hash.

Should I change the default client seed?

Yes, at least once. A seed you choose yourself guarantees the casino could not know it when it committed to its server seed, which is the point of the scheme.

Can a casino cheat with provably fair games?

It cannot change a committed roll without the hash check failing. It can still set a high edge, delay withdrawals or apply unfair terms, which is why the licence and the operator’s record matter as much as the seeds.

Do I need special software to verify rolls?

No. Python 3 includes the hashlib and hmac modules used in our example, and Node.js has the same functions in its crypto module. Avoid relying only on the casino’s own verifier page.

Sources

  1. Stake: provably fair implementation (HMAC_SHA256, seeds, nonce, cursor)stake.com
  2. Stake: provably fair conversions (bytes to floats)stake.com
  3. Stake: provably fair game events (dice roll = float x 10001 / 100)stake.com
  4. Stake Dice game page (RTP 99%, payout table)stake.com
  5. Stake blog: How to play Dice on Stake (1.0102x to 9900x)stake.com
  6. Stake licences (Medium Rare N.V., CGA OGL/2024/1451/0918)stake.com
  7. Spribe Dice (RTP 97%)spribe.co
  8. BetFury Dice (RTP 99.02%, 1.9804x at 50%)betfury.com
  9. NIST FIPS 180-4 Secure Hash Standardcsrc.nist.gov
  10. RFC 2104 HMACrfc-editor.org
  11. Python hmac module documentationdocs.python.org
  12. Gamblers Anonymousgamblersanonymous.org

Checked against these sources on 7 Oct 2026. Found an error? Send a correction.