how-it-works
Server Seed, Client Seed and Nonce, Explained Properly
Server seed, client seed and nonce do three different jobs. Here is exactly what each one contributes, when it is revealed, and how they combine into a result.
Three inputs produce every result in a provably fair game, and they are not interchangeable. The server seed is the operator’s secret and acts as the cryptographic key. The client seed is your string, and its only job is to stop the operator precomputing a sequence for you. The nonce is a counter that increments once per bet, turning one seed into an unlimited sequence.
Miss what each one contributes and verification becomes cargo cult — you run the code, it outputs something, and you have no idea what you just proved. This page fixes that.
The server seed: why you only see a hash
The server seed is a long random string, commonly 64 hexadecimal characters, generated by the operator and held secret for the life of a seed pair. In the standard construction it is the HMAC key.
You are shown SHA-256(serverSeed) before you place a bet. That published hash is the commitment. It fixes the operator to one specific value while telling you nothing usable about what that value is, because SHA-256 cannot practically be run backwards.
The reason for the secrecy is obvious once you state it: if you had the server seed, you could compute the next thousand results and bet only when the outcome was good. The hash gives you the binding without the advantage. This asymmetry is the entire engineering trick behind how provably fair works.
Server seeds are revealed on rotation and only on rotation. A seed that is still in use is still secret, which is why a live session is never verifiable in real time — you are always checking the past.
The client seed: what it actually buys you
The client seed is a string you control. Most sites pre-fill one and let you replace it with anything.
Here is what it does. Without a client input, the operator generates a server seed, computes the entire result sequence it implies, and — if it were dishonest — chooses a seed whose sequence happens to be unprofitable for whoever plays it. The commitment hash would still verify perfectly. You would be checking that the operator did not change a rigged sequence, which is not much of a guarantee.
Your client seed blocks that. The result at each nonce depends on both seeds, so a sequence cannot be selected in advance for a client seed the operator has not seen. Same server seed, three different client seeds, nonce 1:
| Client seed | HMAC-SHA512 digest (first 16 hex) | Float | Dice roll |
|---|---|---|---|
provablyfairplay-01 |
6d62c5b75ae9205d |
0.4272883961 | 42.73 |
provablyfairplay-02 |
30b4e33577c780d4 |
0.1902601246 | 19.02 |
default |
b8b25c500d2e37bc |
0.7214715667 | 72.15 |
One character difference in the client seed, three unrelated sequences.
There is no clever client seed. Length, entropy and character set make no difference to your results, because the value goes through HMAC either way. Anyone selling you a “lucky” client seed strategy is describing a superstition — the mapping is uniform regardless of the input string.
The nonce: the per-bet counter
The nonce is an integer that starts at 0 or 1 (site-dependent) and increments by exactly one with each bet on the current seed pair. It is not random and it is not secret.
Its job is to make each bet a distinct message under the same key. HMAC(serverSeed, "clientSeed:1") and HMAC(serverSeed, "clientSeed:2") are unrelated digests, so one server seed can back thousands of bets without repeating.
It also gives you an index. When you want to check your 47th bet on a seed pair, you recompute with nonce 47 — you do not need to replay the session. Bet histories almost always display the nonce alongside each result for exactly this reason.
Games that need multiple random values per round (plinko’s ball path, mines’ bomb placement, keno’s draw) consume more of the digest or add a cursor field to the message. The binomial structure of plinko is the clearest example: one digest supplies every left-or-right decision down the board.
The exact sequence of events, in time order
| # | When | What happens | What you can see |
|---|---|---|---|
| 1 | Before any bet | Server generates the server seed, keeps it secret | Nothing |
| 2 | Before any bet | Server publishes SHA-256(serverSeed) |
The commitment hash — save it |
| 3 | Before any bet | You set your client seed | Your own string |
| 4 | Bet 1 | Nonce = 1, result derived from both seeds | The result and its nonce |
| 5 | Bets 2…n | Nonce increments once per bet | Results, nonces, running history |
| 6 | You rotate | New server seed generated, its hash published | New commitment hash |
| 7 | Immediately after | Old server seed revealed | The plaintext server seed |
| 8 | Verification | You hash the revealed seed, compare to step 2 | Match or mismatch |
| 9 | Verification | You recompute results at chosen nonces | Reproduced outcomes |
Step 8 is the one people skip, and skipping it removes the entire guarantee. Step 2 is the one that has to happen before you bet — a commitment hash you collect afterwards proves nothing, because the seed could have been chosen after the fact. The full verification walkthrough covers both in detail, including what to do if the hashes disagree.
What a seed pair page usually shows
Interfaces vary, but a seed settings panel typically exposes:
- Active client seed, editable.
- Active server seed hash, the commitment for the seed currently in use.
- Nonce, the count of bets placed on the current pair.
- Previous server seed, in plaintext, once rotated.
- Previous server seed hash, so you can confirm the reveal matches the earlier commitment.
- A rotate or change seed control, which generates a new server seed and reveals the old one in the same action.
Some sites also include a built-in verifier where you paste seeds and a nonce and get a result back. Convenient, and worth exactly nothing as proof, since the page checking the operator’s maths is served by the operator. Run it yourself.
Computing a result from the three inputs
The construction below is the common shape. Site formulas differ — message separator, hash function, how many bytes are consumed — so read the operator’s published algorithm before trusting any output.
const crypto = require('crypto');
const serverSeed = '3f6a1b9c2d8e470a5c1f8b3d6e29a4f70b5d8c1e2a3f4b6c7d8e9f0a1b2c3d4e';
const clientSeed = 'provablyfairplay-01';
const nonce = 2;
const digest = crypto
.createHmac('sha512', serverSeed)
.update(`${clientSeed}:${nonce}`)
.digest('hex');
const value = parseInt(digest.slice(0, 8), 16) / 2 ** 32;
console.log(digest.slice(0, 16)); // 2eb01d3a910fa270
console.log(value); // 0.18237478891387582
console.log(Math.floor(value * 10001) / 100); // 18.23
The same three lines in Python, producing identical output:
import hmac, hashlib
server_seed = "3f6a1b9c2d8e470a5c1f8b3d6e29a4f70b5d8c1e2a3f4b6c7d8e9f0a1b2c3d4e"
client_seed = "provablyfairplay-01"
nonce = 2
digest = hmac.new(server_seed.encode(),
f"{client_seed}:{nonce}".encode(),
hashlib.sha512).hexdigest()
value = int(digest[:8], 16) / 2**32
print(digest[:16]) # 2eb01d3a910fa270
print(value) # 0.18237478891387582
print(int(value * 10001) / 100) # 18.23
Some implementations walk the digest a byte at a time instead — take four bytes and sum byte ÷ 256, byte ÷ 256², byte ÷ 256³, byte ÷ 256⁴. That is arithmetically identical to reading the first eight hex characters as a 32-bit integer and dividing by 4,294,967,296; both give 0.18237478891387582 here. The byte-walk version exists because it extends cleanly when a game needs several values from one digest.
The limit of what these three inputs prove
A verified seed pair tells you the sequence was fixed before your bets and matches the published commitment. It says nothing about the function that turns 0.18237478891387582 into a payout. That mapping is where the house edge lives, and it is set by the operator’s payout table rather than by any cryptography.
It also says nothing about seeds you never rotated, games on the same site that do not expose seeds at all, or whether the reveal you were shown is genuine on a site with no external scrutiny. Those gaps are the subject of what provably fair does not prove, and they are worth reading before you treat a seed panel as a guarantee.
Frequently asked questions
What is a server seed in provably fair gambling?
The server seed is a long random string the operator generates and keeps secret for a session. It acts as the HMAC key that produces every result. Before betting, the operator publishes only its SHA-256 hash as a commitment; the seed itself is revealed when you rotate to a new one, so you can check the hash and recompute results.
Should I change my client seed?
Yes, at least once. Changing it does not make the cryptography stronger, but it removes any possibility that the operator generated a sequence in advance knowing what your client seed would be. Type something arbitrary. Any string works, and there is no advantage to one value over another.
What does the nonce do?
The nonce is a counter that increments by one on each bet with the same seed pair. It changes the HMAC message every bet, so the same server and client seeds produce a different result each time. It also gives you an index — to verify bet number 47, you recompute with nonce 47.
Why is the server seed only shown as a hash?
Because the seed is the key that generates results. If it were published before betting, you could compute the next hundred outcomes and bet only on the winners. The hash commits the operator to one value while keeping it unusable to you until the seed is retired and revealed.
How often should I rotate my seed pair?
Rotate whenever you want to verify — rotation is what triggers the reveal. Many players rotate at the end of each session or after any result they want to check. There is no cryptographic decay in a long-lived seed, but a seed you never rotate is a seed you never get to verify.
Can two players have the same server seed?
Implementations vary. Most per-player provably fair systems issue a distinct server seed per player seed pair, so your nonce sequence is yours alone. Shared-outcome games like multiplayer crash typically use one round seed for everyone, often combined with public inputs. The site's own documentation is the only reliable answer.