Provably fair dice explained step by step
What you will be able to do
By the end of this guide you will be able to take a dice bet's seeds and nonce and work out the roll by hand, with nothing hidden. We computed every number below in Python using the standard hmac and hashlib modules, and you can reproduce them in our verifier.
The scheme is the common one used by many crypto casinos for dice:
- Random bytes:
HMAC-SHA256(serverSeed, clientSeed:nonce:round) - Float: four bytes per float,
b1/256 + b2/256^2 + b3/256^3 + b4/256^4 - Roll:
floor(float x 10001) / 100
Casinos can differ, so check the casino's own fairness page before relying on this formula.
Where to find the values
At most casinos the values you need sit in a panel called "Fairness", "Provably fair" or "Seeds", reachable from the game screen or your account settings. Clicking a bet in your history usually shows its client seed, nonce and the hashed server seed it used. The server seed itself appears only after you rotate the seed pair, often in a list of previous or revealed seeds. Copy each value exactly. Before you play, save the hashed server seed somewhere outside the casino, because that saved copy is what you check the revealed seed against. Our page on using the verifier lists where each value usually lives and how to read the result.
The inputs
| Input | Value |
|---|---|
| Server seed (revealed after rotation) | a7c41e09d5b3f28e6c1d4a90b7e35f12c8d06e4b9a2f71c35e8d0b6a4f19c27e |
| Hashed server seed (shown before play) | 3e29712c704eeff2d868f958cf08e44a1a16ecba4c974af0496e13bccdefaff2 |
| Client seed | maple-leaf-2026 |
| Nonce | 0 |
| Round | 0 |
These are example seeds made up for this guide.
Step 1: check the commitment
Hash the server seed as text with SHA-256:
SHA-256("a7c41e09...4f19c27e") = 3e29712c704eeff2d868f958cf08e44a1a16ecba4c974af0496e13bccdefaff2
It matches the hashed server seed shown before play, so the casino used the seed it committed to. If it did not match, nothing below would be worth checking. Our guide on server seed hashing explains the common causes of a false mismatch.
Step 2: build the message
Join the client seed, nonce and round with colons:
maple-leaf-2026:0:0
Dice needs only one float, and one HMAC gives eight, so the round stays at 0. The nonce is the bet number within this seed pair. Some casinos start it at 1 instead of 0.
Step 3: compute the HMAC
Compute HMAC-SHA256 with the server seed as the key and the message as the data. HMAC is defined in RFC 2104 and NIST FIPS 198-1. The output is 32 bytes, shown here as 64 hex characters:
bea6dafadb325af8baff8145e3bb9406f7734638ecde39e473200c87fabb0ce0
Step 4: take the first four bytes
Each pair of hex characters is one byte:
| Hex | be | a6 | da | fa |
|---|---|---|---|---|
| Decimal | 190 | 166 | 218 | 250 |
Step 5: turn the bytes into a float
Divide each byte by a growing power of 256 and add the results:
| Term | Calculation | Value |
|---|---|---|
| b1 / 256 | 190 / 256 | 0.7421875 |
| b2 / 256^2 | 166 / 65,536 | 0.002532958984375 |
| b3 / 256^3 | 218 / 16,777,216 | 0.0000129938... |
| b4 / 256^4 | 250 / 4,294,967,296 | 0.0000000582... |
| Float | sum | 0.744733511004597 |
Another way to see it: the four bytes form the 32-bit number 3,198,606,074, and the float is that number divided by 2^32 (4,294,967,296). The result is always at least 0 and below 1.
Step 6: turn the float into a roll
Multiply by 10,001:
0.744733511004597 x 10001 = 7448.0798...
Round down to a whole number: 7448.
Divide by 100: 74.48.
That is the roll for this bet.
Why 10,001?
The roll can be any value from 0.00 to 100.00 in steps of 0.01. That is 10,001 possible values, not 10,000, because both ends are included. Multiplying by 10,001 and rounding down gives a whole number from 0 to 10,000, and dividing by 100 gives the two-decimal roll.
Step 7: decide win or loss
The roll is only half the bet. Your bet settings decide the outcome. Suppose you bet "roll under 50.00":
- 74.48 is not under 50.00, so this bet loses.
If you had bet "roll over 50.00", it would win. Casinos usually show a win chance and a payout multiplier for your target. The gap between the true chance and the multiplier is the house edge. Provably fair proves the roll was not tampered with; it does not change that edge.
The next bets in the same session
Keep the seeds the same and increase the nonce by one for each bet:
| Nonce | Message | First 4 bytes | Float x 10001 | Roll |
|---|---|---|---|---|
| 0 | maple-leaf-2026:0:0 | 190, 166, 218, 250 | 7448.08 | 74.48 |
| 1 | maple-leaf-2026:1:0 | 84, 225, 67, 46 | 3315.95 | 33.15 |
| 2 | maple-leaf-2026:2:0 | 96, 184, 213, 115 | 3778.58 | 37.78 |
| 3 | maple-leaf-2026:3:0 | 146, 176, 213, 148 | 5730.68 | 57.30 |
With "roll under 50.00", nonces 1 and 2 win and nonces 0 and 3 lose. Every result is fixed by the seeds and nonce, and you can reproduce each one.
The code we used
This is the Python we ran to produce the numbers above. It uses only the standard library.
import hashlib, hmac, math
server_seed = "a7c41e09d5b3f28e6c1d4a90b7e35f12c8d06e4b9a2f71c35e8d0b6a4f19c27e"
client_seed = "maple-leaf-2026"
print(hashlib.sha256(server_seed.encode()).hexdigest())
for nonce in range(4):
msg = f"{client_seed}:{nonce}:0".encode()
digest = hmac.new(server_seed.encode(), msg, hashlib.sha256).digest()
b = digest[:4]
f = b[0]/256 + b[1]/256**2 + b[2]/256**3 + b[3]/256**4
roll = math.floor(f * 10001) / 100
print(nonce, digest.hex(), list(b), f, roll)
Swap in your own revealed server seed, client seed and nonce to check your bets. If your casino starts nonces at 1, start the range at 1.
Is the conversion biased?
A float built from four bytes has 2^32, or 4,294,967,296, possible values. Spreading them over 10,001 rolls does not divide evenly: 4,294,967,296 = 10,001 x 429,453 + 7,843. So 7,843 roll values come from 429,454 possible byte patterns and the other 2,158 come from 429,453. The difference is about 1 in 429,000 per roll value, far too small to matter to a player and far smaller than any house edge.
Common reasons your roll does not match
- Nonce off by one. Try the nonce above or below.
- Wrong client seed. If you changed it during the session, earlier bets used the old one. Check the bet details. Our guide on changing your client seed covers this.
- Wrong seed pair. Make sure the revealed server seed belongs to the period of the bet.
- Different scheme. Some casinos use a different message format, put the client seed in the key, or use a different dice formula.
- Copy errors. A trailing space in the client seed changes the HMAC completely.
If every input is correct, the casino documents this scheme, and the roll still differs, save screenshots of the bet, the seeds and the documentation and contact the casino. Our guide to verifying a bet covers what to do next.
Play within limits
Dice is fast. At several bets a second the house edge applies to a large total wagered very quickly. Set a limit before you start and see our responsible gambling page if it stops being fun.
Sources
- RFC 2104, HMAC: Keyed-Hashing for Message Authentication: https://datatracker.ietf.org/doc/html/rfc2104
- NIST FIPS 198-1, The Keyed-Hash Message Authentication Code (HMAC): https://csrc.nist.gov/pubs/fips/198-1/final
- NIST FIPS 180-4, Secure Hash Standard: https://csrc.nist.gov/pubs/fips/180-4/upd1/final
- Python documentation, hmac module: https://docs.python.org/3/library/hmac.html
- Python documentation, hashlib module: https://docs.python.org/3/library/hashlib.html
Key terms
- Dice
- Seed-verifiable game where you set a target number and predict if the random roll lands above or below it.
- HMAC
- A hash function that takes a secret key; provably fair games run HMAC-SHA256 over the server seed, client seed and nonce.
- SHA-256
- A cryptographic hash that maps any input to a fixed 256-bit digest; casinos use it to commit to server seeds.
- Server seed
- The casino's secret random value that, together with your client seed and the nonce, decides each bet result.
- Hashed server seed
- The SHA-256 digest of the casino's secret server seed, published before any bet as proof the seed is locked in.
- Client seed
- The player's own input to every provably fair result, set or edited by you so the casino cannot work out outcomes in advance.
- Nonce
- A bet counter that goes up by one for each wager on the same seed pair, so no two bets share a result.
- House edge
- The average percentage of every wager that a game is built to keep for the casino.