FAIRNESS STUDIES

What a hash commitment proves, and the three things it cannot

Illustration for “What a hash commitment proves, and the three things it cannot”
A hash commitment is the SHA-256 fingerprint of the house’s server seed, shown to you before any round is played. Because a hash cannot be reversed and no two different seeds share one, publishing it pins the seed down: when the seed is revealed later, hashing it must reproduce the fingerprint you saw. That proves three things. The seed was fixed before your bets. The revealed seed is the committed one. Each result follows from that seed, your client seed and the round number by the published function, which you can recompute in your own browser. It does not prove three others. It cannot show that the server seed was chosen at random rather than picked, which is why the order in which seeds are committed and client seeds are set matters, and why this site’s panel has a boundary described below. It cannot make a game fair in the sense of having no house edge; the return is a separate, published number. And it proves nothing about rounds nobody verifies. The commitment is a receipt for the randomness, not a certificate for the game.
BETKYO RESEARCHPUBLISHED 2026-09-07UPDATED 2026-09-079 MIN READ

The trick, in one paragraph

A cryptographic hash turns any input into a fixed-length fingerprint with two properties that matter here: you cannot work backwards from the fingerprint to the input, and you cannot find two inputs with the same fingerprint. So if someone shows you the fingerprint of a secret today and the secret tomorrow, you can hash the secret and check that it matches. If it does, the secret they showed you is the one they had yesterday. They could not have swapped it in between, because a different secret would have a different fingerprint, and they could not have chosen the secret to fit the fingerprint, because that would mean reversing the hash.

That is a commitment scheme, and it is the whole cryptographic content of “provably fair”. The house generates a server seed, publishes its SHA-256 hash, plays rounds derived from the seed, and reveals the seed when the pair is retired. Everything else is plumbing.

ENGINE-VERIFIED_shared/seedApi.ts: getRandomKey returns {serverSeedHashed, clientSeed, nonce}; renewRandomKey returns a fresh pair together with previousServerSeed and previousServerSeedHashed, the reveal. _shared/SeedPanel.tsx labels the field “server seed (sha-256 commitment)”. _shared/rng.ts: sha256Hex() computes the fingerprint and hmacSha256Utf8() the per-round hash, with the comment that the demo engine “GENERATES outcomes with the same primitives the verifier uses to CHECK them — one implementation, so the demo can never drift from what the verifier accepts”.

Three things it proves

What the commitment establishes, and how you check each one
CLAIMWHY IT HOLDSTHE CHECK
The server seed was fixed before your betsAny change to the seed would change its hash, and the hash was shown before the first roundNote the commitment in the seed panel before you play
The revealed seed is the committed oneA different seed cannot produce the same SHA-256 fingerprintHash the revealed seed; compare with the commitment you noted
Each result follows from the seed pair and the round numberThe result is HMAC-SHA256(server seed, “client seed-nonce-cursor”) passed through the game’s published derivationRecompute the round in your browser from the four inputs; the panel does this for you

All three checks are local: they need the revealed seed, your client seed, the nonce and the derivation code, and nothing from the house at check time.

The third claim is the one that does the work for a player, and it depends on the derivation being public. A hash of the seed tells you nothing about how the seed became a dice roll or a card. Here that function ships in the client, the same code the demo uses to generate results and the verifier uses to check them, so a recomputed round is a real recomputation rather than a request to the server to confirm itself.

ENGINE-VERIFIED_shared/demoLocal.ts: uAt() derives the per-round number as u64(hmacSha256Utf8(serverSeed, `${clientSeed}-${nonce}-${cursor}`)), described as matching RandomUtils.generateHash on the server; _shared/rng.ts turns the first seven bytes of the HMAC into a uniform number in [0, 1) “matching the server’s Long→Double rounding bit-for-bit”. Each game’s derive module then maps that number to a roll, a card or a multiplier.

The verification walkthrough does all three steps on a real round. If you have never done it, do it once; the point of the scheme is not that you check every round but that you could check any of them, and the house cannot tell in advance which.

Three things it cannot prove

It cannot prove the seed was random. A commitment pins a seed down; it says nothing about how the seed was chosen. If the house knew your client seed when it generated the server seed, it could in principle generate seeds until it found one whose first rounds it liked, and commit to that one. The hash would check out perfectly. The standard defence is ordering: the server seed is committed first, and the client seed is set afterwards, so that whatever the house committed to, it did not know what it would be combined with.

That ordering is where this site’s panel has a boundary worth stating plainly. Setting a client seed here does not leave the current server seed in place; it rotates the pair, and the new server seed is generated by the same request that carries your new client seed. From the client it is not possible to show that the new seed was fixed before the request was read. Whether the server pre-generates the next seed, as some operators do by publishing the next commitment in advance, is not visible in the client’s API, and there is no “next server seed hash” field to check against. This has been raised with the game team, and the fix is a small one: commit the next server seed before the client seed that will be paired with it is accepted, and show that commitment in the panel.

ENGINE-VERIFIED_shared/seedApi.ts: setClientSeed(clientSeed) calls renewRandomKey with the new client seed and returns a fresh pair at nonce 0; rotate() calls the same endpoint without a seed. IHouseSeed carries serverSeedHashed, clientSeed and nonce, plus the previous pair on rotation; no next-seed commitment is present in the type.

Until then, the practical version of the defence is the one the scheme already gives you in every other respect: the reveal. A house grinding seeds against your client seed would still have to reveal each seed at rotation, and every round under it can be recomputed. What the boundary means is that a suspicious streak in the first rounds after a seed change cannot be ruled out by the hash alone; it can only be examined, round by round, after the reveal.

It cannot prove the game is fair in the other sense. “Provably fair” means the randomness was honest, not that the odds are even. A dice game can be perfectly verifiable and still return 99% by design; the edge lives in the payout table, which is a published number and a separate promise. The ethics of the house edge is about that promise. The commitment is silent on it.

It proves nothing about rounds nobody checks. The scheme is a deterrent, not a guarantee. A round you never recompute is a round you have taken on trust, exactly as you would anywhere else; what changes is that the trust is optional, and the house cannot know when you will exercise it. That is a large improvement on a shuffling machine you cannot see inside, and a smaller one than the word “proof” suggests.

The hash is a receipt for the randomness. It is not a certificate for the game.the sentence to remember

What would prove more

  • A pre-committed next seed. Publishing the hash of the next server seed before any client seed can be paired with it closes the ordering gap above. It is the single change that would let the panel prove the seed was fixed before your input was known.
  • A public source of randomness. Mixing in a beacon that nobody controls, such as the drand network, removes the question of who chose the seed altogether; inside drand describes how that works and what it costs.
  • A published derivation, kept public. Already the case here, and the part most easily lost when a client is rewritten. The verifier is only as honest as the code it runs.

None of these changes what a hash is. They change what the hash is a fingerprint of, and when. The scheme is simple enough that its limits are simple too, and a player who knows the three things it proves is in a better position than one who has been told it proves everything.

FAQ

What is a hash commitment in a provably fair casino?

The SHA-256 fingerprint of the house’s secret server seed, shown before play and checked against the seed when it is revealed. It proves the seed was fixed before your bets and that the revealed seed is the one committed to.

Does a matching hash prove the game was fair?

It proves the randomness was not altered after commitment and, with a published derivation, that each result follows from the seed pair. It does not prove the seed was chosen randomly, and it says nothing about the house edge, which is a separate published number.

Can the house pick a server seed that favours it?

Only if it knows the client seed the server seed will be paired with when it chooses. The defence is to commit the server seed before the client seed is set. On this site a client seed change rotates the pair in the same request, so that ordering cannot be confirmed from the client; the article describes the boundary and the fix that has been proposed.

How do I check a round myself?

Rotate the seed to reveal the retired server seed, hash it to confirm it matches the commitment you were shown, then recompute HMAC-SHA256 of the server seed over your client seed, the nonce and the cursor, and pass the result through the game’s published derivation. The seed panel performs the recomputation in your browser.

Why is the derivation code important?

Because the hash only pins the seed. Turning the seed into a roll or a card is a function, and unless that function is public a matching hash tells you nothing about whether the result was the one the seed implied. Here the client ships the same derivation the demo uses to generate outcomes.

Is provably fair better than a licensed RNG audit?

They answer different questions. An audit certifies a generator’s statistical behaviour over many draws; a commitment lets you check a specific round after the fact. Neither replaces the other, and neither changes the house edge.

SOURCES & REFERENCES
THE GAMES IN THIS ARTICLE
Betkyo Research — written by the team that builds these games. Every probability quoted in the Journal is derived from our engine source or a cited reference, never copied from another site. Figures are re-checked whenever the engines change.

18+ · PLAY RESPONSIBLY · THE JOURNAL IS EDITORIAL CONTENT, NOT BETTING ADVICE