How server seed hashing works
The job the hash does
A provably fair casino has a problem to solve. It must keep its server seed secret while you play, because anyone who knows it can predict results. But it must also prove later that it did not change the seed after seeing your bets. A hash solves both at once.
Before you play, the casino shows you the SHA-256 hash of the server seed. That hash is a commitment: it reveals nothing useful about the seed, yet it fixes which seed the casino must reveal later. When the seed is revealed after rotation, you hash it yourself and compare. A match proves the casino used the seed it committed to.
This guide explains how that works and how to check a hash correctly. For the wider scheme, see what is provably fair.
What SHA-256 is
SHA-256 is a hash function specified by NIST in FIPS 180-4, the Secure Hash Standard. It takes input of any length and produces a 256-bit output, usually written as 64 hexadecimal characters.
A standard test value from FIPS 180-4 is the three-letter text abc. Its SHA-256 hash is:
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
If a tool gives you this result for abc, it computes SHA-256 correctly. It is a quick way to check a website or script before you rely on it.
The three properties that make the commitment work
| Property | What it means | Why it matters to you |
|---|---|---|
| Deterministic | The same input always gives the same hash | You can recompute the hash yourself and get the casino's exact value |
| Preimage resistant | Given a hash, finding an input that produces it is not feasible | The hash does not reveal the seed, so future results stay unpredictable |
| Collision resistant | Finding two different inputs with the same hash is not feasible | The casino cannot reveal a different seed later that matches the same hash |
The second and third properties depend on the seed being hard to guess, which comes up below.
A worked example
We computed these values in Python with the standard hashlib module.
Server seed (as text):
a7c41e09d5b3f28e6c1d4a90b7e35f12c8d06e4b9a2f71c35e8d0b6a4f19c27e
SHA-256 of that text:
3e29712c704eeff2d868f958cf08e44a1a16ecba4c974af0496e13bccdefaff2
One character changes everything
Change only the last character of the seed, from e to f, and the hash becomes:
af4391b73bb5adf912b7a7296ee8f79dda892ddbb47e5e4c38efeaaf2d82de7c
There is no visible relation between the two hashes. This is why a near-match means nothing: either every character matches or the commitment has failed.
Text or bytes: the most common cause of a false alarm
A server seed is usually shown as 64 hexadecimal characters. Those characters can be hashed in two different ways:
- As text. The 64 characters themselves are the input.
- As bytes. The hex is first decoded into 32 raw bytes, and those bytes are the input.
For our example seed:
| Method | SHA-256 |
|---|---|
| Hash the text | 3e29712c704eeff2d868f958cf08e44a1a16ecba4c974af0496e13bccdefaff2 |
| Hash the decoded bytes | 3667286ec9562c47723de3aa95a788fe2fa47fed883550be45a053e5d390c64e |
Both are valid SHA-256 results of different inputs. The common scheme hashes the text exactly as displayed, and that is what our verifier does. If your hash does not match, read the casino's fairness documentation to see which method it uses before drawing conclusions.
Two more ways to get the wrong hash
A hidden newline
On Linux and macOS, echo adds a newline to the end of its output. Hashing with echo seed | sha256sum therefore hashes the seed plus a newline. For our example seed that gives:
60f1c7bdca64b07819a42ddf185c24d093fe41bce96f41f029422f16bc9c50b5
which does not match. Use printf %s seed | sha256sum or echo -n seed | sha256sum instead. The same problem appears if you copy a seed with a trailing space or line break.
Changed letter case
Hex can be written in lower or upper case, but hashing the text treats a and A as different characters. If the casino shows lower case, hash lower case.
Checking a hash yourself
Any of these works, using the seed exactly as the casino shows it:
- Our verifier: paste the server seed and compare the hash it shows.
- Python:
hashlib.sha256(seed.encode()).hexdigest() - A terminal:
printf %s 'seed' | sha256sum
Compare all 64 characters with the hash you saved before playing, not with the hash the casino shows you now. A dishonest site could change both the revealed seed and the displayed hash in its history. Your saved copy is the only one it cannot change.
Why the seed has to be long and random
The commitment hides the seed only if the seed cannot be guessed. SHA-256 is fast, so an attacker can try many inputs per second.
To show this, we hashed the six-digit seed 482913, then tried every number from 000000 to 999999 until one matched. A plain Python loop on an ordinary computer found it in well under a second. A seed with a million possibilities offers no secrecy at all.
A 64-character hex seed represents 256 bits, which is far beyond what anyone can search. Good casinos generate seeds with a cryptographically secure random number generator. You cannot check how a seed was generated, but you can check that revealed seeds are full length and never repeat. A short, patterned or reused seed is a finding worth reporting.
Where HMAC fits
The hash commits to the seed. A different construction turns the seed into results: HMAC-SHA256, defined in RFC 2104 and in NIST FIPS 198-1. In the common scheme the server seed is the HMAC key and clientSeed:nonce:round is the message. HMAC is designed so that output for one message does not let you work out the key or predict output for another message. That is why seeing your past results does not reveal the server seed. Our dice walkthrough shows HMAC step by step.
What the hash does not prove
- That the seed was chosen fairly. The hash fixes the seed; it does not show how it was picked. The client seed handles that, because the casino cannot tailor a seed to a value it has not seen.
- That results were computed from it. You prove that by recomputing bets.
- Anything about third-party games. Slots and live tables do not use your seeds.
Hash chains in multiplayer games
Some shared-result games, such as many crash games, do not use per-player seeds. Instead the operator generates a long chain where each game's seed is the SHA-256 hash of the next game's seed, and publishes the final hash in advance. Because hashing only works one way, the operator cannot change future games without breaking the chain, and anyone can check a revealed game by hashing it forward. Details differ widely between casinos, so use each casino's own instructions for these games.
Quick checklist
| Check | Done? |
|---|---|
| Saved the hashed server seed outside the casino before playing | |
Tested my hashing tool with the abc test value |
|
| Hashed the revealed seed as text, with no trailing space or newline | |
| All 64 characters match the saved hash | |
| Revealed seed is full length and not a repeat |
Sources
- NIST FIPS 180-4, Secure Hash Standard: https://csrc.nist.gov/pubs/fips/180-4/upd1/final
- 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
- Python documentation, hashlib module: https://docs.python.org/3/library/hashlib.html
- Python documentation, hmac module: https://docs.python.org/3/library/hmac.html
Key terms
- SHA-256
- A cryptographic hash that maps any input to a fixed 256-bit digest; casinos use it to commit to server seeds.
- 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.
- Server seed
- The casino's secret random value that, together with your client seed and the nonce, decides each bet result.
- Seed rotation
- Swapping the active server seed for a fresh one, which discloses the old seed so you can verify its bets.
- HMAC
- A hash function that takes a secret key; provably fair games run HMAC-SHA256 over the server seed, client seed and nonce.
- 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.
- Crash game
- A round-based game with a multiplier that climbs from 1x until it crashes; you win only if you cash out first.
- Provably fair
- A cryptographic method that lets you confirm a game result was set before your bet and left untouched afterwards.