Every provably fair bet is computed from three inputs: a server seed the casino generates and commits to in advance, a client seed you control, and a nonce that counts your bets. The casino cannot change a result after seeing your bet, because its seed was hashed and shown to you first; you cannot predict a result, because the raw server seed stays secret until you rotate. This split of control is the entire trick — here is each number in detail, then a worked example down to the bytes.
What is the server seed?
A long random secret — typically 64 hex characters — generated by the casino. You never see it while it is active. What you see instead is its SHA-256 hash, published before you bet. That hash is a commitment: SHA-256 is a one-way function, so the site cannot find a different seed that produces the same hash, and it cannot change the seed without the mismatch being visible. When you rotate, the raw seed is revealed and every bet made under it becomes checkable.
What is the client seed?
A short value attached to your account, and on most sites you can type in your own. It exists so the casino cannot pre-compute outcomes: even if it generated a million server seeds looking for one that beats you, it would not know which client seed you will use. Changing it to something of your own choosing is the one free move you have in this protocol — take it. In multiplayer games no single player can be trusted to pick the seed, so PvP modes replace it with a public value such as an EOS block hash; that variant gets its own article in How Case Battles, Crash and Jackpot Stay Fair.
What is the nonce?
A counter. It starts at 0 when a seed pair is created and goes up by one with every bet. Its job is uniqueness: without it, the same seed pair would produce the same result on every bet. Because it is a plain incrementing number, it also gives you an audit trail — if your bet history shows 500 bets under a seed pair, the nonces should run 0 through 499 with no gaps.
| Input | Who sets it | When you see it | What it prevents |
|---|---|---|---|
| Server seed | Casino | Hash up front; raw seed after rotation | The site changing results after your bet |
| Client seed | You | Always | The site pre-computing outcomes before assigning seeds |
| Nonce | Protocol (counter) | Always, per bet | Identical results repeating; silent skips in your history |
How do the three combine into a result?
The widely documented construction — Stake publishes it in full, and most originals-style implementations follow the same shape — uses HMAC-SHA256 with the server seed as the key and the other two inputs as the message:
resultHex = HMAC-SHA256(serverSeed, clientSeed + ':' + nonce)HMAC produces 32 bytes, and the game consumes them 4 at a time — enough for 8 random values. Games that need more (dealing a blackjack shoe, for instance) append a cursor to the message (clientSeed:nonce:cursor) and increment it for each additional 32-byte block. For a single dice roll, the first 4 bytes are all you need.
A worked example, byte by byte
Demo values, chosen so you can reproduce every line yourself:
serverSeed = d8e2c9a41b7f30e6558a2c4d9b1e6f03a7c85d21e4b90f6c3a1d5e8b2f7c4a90
clientSeed = highlighted-demo
nonce = 7
commitment shown before play:
SHA-256(serverSeed) = 34a02fe0999787f4227f9438a297439f02aaccd7ead624d49552ef9955b5a99eNow the bet itself. HMAC the message highlighted-demo:7 with the server seed as key:
HMAC-SHA256(serverSeed, 'highlighted-demo:7') =
ebe161ba2e6860ef2f32e6f5d2e517bf3694fd1859cc78e36ef437e950194494
first four bytes: eb e1 61 ba
as integers: 235 225 97 186
float = 235/256 + 225/256² + 97/256³ + 186/256⁴
= 0.91796875 + 0.00343323 + 0.00000578 + 0.00000004
= 0.92140780Each byte contributes 256 times less than the one before it — the same idea as decimal places, in base 256. The result is a float uniformly distributed between 0 and 1. The last step maps it onto the game. A dice-style game with outcomes from 0.00 to 100.00 has 10,001 possible results, so:
roll = floor(0.92140780 × 10001) / 100 = 92.14That mapping is the dice one; a roulette maps the float onto pockets, crash feeds it into a multiplier curve, and a case opening maps it onto ticket ranges per item. The float generation is identical everywhere — only the final line changes. Sites with provably fair originals, like Gamdom with its crash, dice and roulette lineup, document their mappings on their fairness pages, as does CSGORoll for its roll and PvP games.
Who controls what — and why it matters
The casino controls the server seed but committed to it before your bet. You control the client seed, which the casino had to accept before knowing what it would be. Nobody controls the nonce — it just counts. So the casino cannot steer a result without breaking its own commitment, and you cannot predict one without breaking SHA-256. What the protocol cannot do is force you to check: if you never rotate and never verify, the guarantees exist only on paper. Our step-by-step verification guide shows the full loop, and the verifier tool runs this exact byte math in your browser with an explain mode that shows every intermediate value.
All three numbers together decide only which outcome you get, never how good the outcomes are. What the outcomes pay was fixed in the paytable before any seed was generated — see Provably Fair ≠ Good Odds.