Provably fair5 min read

Provably fair gambling: server seeds, client seeds and nonces

How a provably fair game locks in a hidden server seed, mixes in your client seed and a nonce, and what the check does and doesn't prove.

Fact-checked 18 October 2026 · 7 sources

A provably fair game gives you everything you need to recompute each result yourself. The casino locks in its secret before you bet, you add a secret of your own, and every outcome is a fixed function of the two plus a bet counter. This article explains each piece, why the order matters, and where the guarantee stops.

The problem it solves

At a physical table you can watch the wheel spin. Online, a result is a number sent by a server, and nothing on your screen tells you whether that number was picked after the server saw your bet. Provably fair schemes don't ask for trust. They make the server commit to its part in advance and publish enough afterwards for you to check its work.

The tool comes from cryptography and is called a commitment scheme. In the commit phase one party fixes a value while keeping it hidden. In the reveal phase it discloses the value, and the other side checks that it is the one committed to. A good commitment is hiding (it gives away nothing about the value) and binding (the committer can't later open it to a different value). The idea is older than online casinos: one of the earliest papers to use it, by Manuel Blum in 1981, was called "Coin Flipping by Telephone".

The server seed and its hash

The casino's half of the randomness is the server seed, a long random string. Before you bet, you see only its SHA-256 hash.

SHA-256 is one of the hash functions in NIST's Secure Hash Standard, FIPS 180-4. It turns any input into a 256-bit digest, and changing one character of the input changes the digest completely. No published attack breaks the full function: working back from a digest to an input means brute force on the order of 2²⁵⁶ guesses, and even finding two inputs with the same digest takes about 2¹²⁸. That is what makes the hash a commitment. You can't recover the seed from it, and the casino can't later produce a different seed that matches it.

The client seed

Your half is the client seed. Its job is to stop the casino from choosing a server seed that suits it. If the server knew your seed in advance, it could try many server seeds and keep one that produced bad results for you, a weakness a 2019 MIT student paper on provably fair schemes spells out.

So the order is the whole point: the server seed is committed first, and the client seed is set after that commitment. A client seed generated for you by the site works mechanically, but then you are trusting that it wasn't picked together with the server seed. Typing your own, any string you like, removes that question.

The nonce

One seed pair is used for many bets, and identical inputs would give identical results. A counter called the nonce (short for "number used once") fixes this. It starts at 0 and goes up by one with each bet, so every bet with the same pair gets fresh randomness that is still fixed in advance.

From seeds to a result: HMAC-SHA256

The inputs are combined with HMAC, a keyed hash defined in RFC 2104 in 1997. HMAC runs the hash twice with the key mixed in each time: H((K ⊕ opad) ∥ H((K ⊕ ipad) ∥ message)). With SHA-256 as the hash, the output is 32 bytes. Without the key they are indistinguishable from random (HMAC has been proven to be a pseudorandom function, given an assumption about the hash inside it), and anyone who has the key can reproduce them exactly.

On cs2.casino the server seed is the key, and the message is your client seed, the nonce and a block number joined by colons:

  • block k = HMAC-SHA256(server seed, "client seed:nonce:k")
  • each block is cut into 8 floats of 4 bytes each
  • float = b0/256 + b1/256² + b2/256³ + b3/256⁴, a number from 0 up to (not including) 1

A dice roll needs one float: roll = floor(float × 10000) / 100, which gives 0.00 to 99.99. Games that need more numbers read more floats. Plinko uses one per row (up to 16) and blackjack reads a 52-card shoe, so they continue into block 1, block 2 and so on. The step-by-step verification guide takes a made-up dice bet through every stage with real commands.

Rotating the pair and checking

While a seed pair is active, its server seed has to stay secret, otherwise you could compute your next results before betting. To check your bets you rotate the pair. On cs2.casino, rotating reveals the old server seed so that every bet made with it can be checked:

  1. Hash the revealed server seed with SHA-256 and compare it with the hash you were shown before betting.
  2. Recompute HMAC-SHA256 with that seed, your client seed and the bet's nonce.
  3. Apply the game's published rule to the floats and compare with the recorded result.

If step 1 fails, the seed was swapped. If step 3 fails, the result didn't come from the committed inputs. The calculator on the provably fair page does the hashing and the arithmetic in your browser. To try the whole loop without staking anything, cs2.casino accepts zero bets (amount 0), which take the next nonce like a real bet.

Shared rounds: hash chains and beacons

Crash and roulette rounds are played by everyone at once, so they can't use your personal seeds. The usual answer is a hash chain: a secret is hashed over and over, the last hash is published before the first round, and rounds use the chain backwards, so each round's seed hashes to the previous one and none can be swapped later. Because the operator generated the chain, it could still know results early. Mixing each seed with a public random value released only after betting closes removes that. The drand article explains the beacon used for this and how the two parts fit.

What provably fair does not prove

The check is narrow, and it helps to be clear about its limits.

  • It doesn't make a game favourable. The house edge lives in the payout rules, not in the randomness. A dice game that pays (1 − edge) / chance is perfectly verifiable and still returns less than you stake on average. The house edge article shows what that costs over many bets.
  • It doesn't prove the randomness was good. A commitment only proves a value wasn't changed. In a 2015 blog post, Jonas Nick showed that a CS:GO jackpot site's commitments were genuine, yet the numbers behind them came from JavaScript's Math.random, which he could predict from a few published results. The MIT paper lists other design flaws, such as seed spaces small enough for the house to search.
  • It only covers bets someone checks. The proof is there after the fact. If nobody recomputes anything, a broken implementation can go unnoticed.
  • It says nothing about the operator. Whether a site pays withdrawals, protects accounts or is allowed to operate where you live are separate questions, covered in how to check a CS2 gambling site.

Sources