18+ only. Gamble responsibly.Rankings updated November 2026How we test
provablylegit Sign in

How to verify a provably fair bet

What you need

To verify one bet you need:

  • The server seed used for the bet, revealed after rotation.
  • The hashed server seed you were shown before playing.
  • The client seed active when you placed the bet.
  • The bet's nonce.
  • The game and any settings that affect the outcome, such as plinko rows and risk, or number of mines.

You also need the casino's documentation of its scheme, because implementations differ.

Step 1: record the commitment before you play

Open the casino's fairness or seed settings and copy the hashed server seed. Store it outside the casino: a note, a screenshot, a message to yourself. This step is often skipped, and it is the one that protects you if the casino later shows a different hash in its history.

While you are there, change the client seed to something of your own. Write it down.

Step 2: play and note your bets

Play normally. If you want to verify specific bets, note their bet IDs or nonces from your history.

Step 3: rotate the seed pair

Click rotate, change seed or similar. The casino reveals the old server seed and shows a new hash for the next one. Your nonce resets.

Step 4: check the hash

Compute the SHA-256 hash of the revealed server seed and compare it with the hash you recorded. In the common scheme, the hash is computed over the seed as text, exactly as displayed. Every character must match.

If it does not match, check you have the right seed pair. If you do, the commitment has failed, and no result from that seed can be trusted.

Step 5: recompute the random numbers

The common scheme generates bytes like this:

HMAC-SHA256(key = serverSeed, message = clientSeed:nonce:round)

  • The key is the server seed.
  • The message joins the client seed, nonce and round with colons. Round starts at 0.
  • Each HMAC produces 32 bytes.

Bytes are turned into floats four at a time. For bytes b1, b2, b3, b4:

float = b1/256 + b2/256^2 + b3/256^3 + b4/256^4

This gives a number from 0 up to, but not including, 1. One HMAC gives 8 floats. If a game needs more, the round number increases to 1, 2 and so on, and the bytes continue from the new HMAC. This is the cursor.

Worked example

Using made-up seeds:

Value Example
Server seed 5f3c9a1e7b2d4c6f8a0e1b3d5c7f9a2e4b6d8c0f1a3e5b7d9c2f4a6e8b0d1c3f
Hashed server seed (SHA-256 of the seed text) c498ac2d22fbdecd7e5ad767c84166d53b7fe56abe1db19415a8197da745c7de
Client seed my-client-seed
Nonce 0
HMAC message my-client-seed:0:0
HMAC-SHA256 output e946af2393f1e064d53af4f70125abe23306dca539cf9f4e88f1c58b5f154d12
First four bytes 233, 70, 175, 35
First float 0.91123...

233/256 + 70/65,536 + 175/16,777,216 + 35/4,294,967,296 = 0.91123 to five places.

You can paste the server seed and client seed into our verifier and check the hash and the dice result in this table.

Step 6: apply the game formula

Each game turns floats into a result. These are the common formulas; casinos may use different ones.

Dice

roll = floor(float x 10,001) / 100

This gives a result from 0.00 to 100.00. In the example, 0.91123 x 10,001 = 9,113.2, floored to 9,113, giving a roll of 91.13.

Limbo

A common approach is:

result = floor((1 - houseEdge) / float x 100) / 100, with a minimum of 1.00.

With a 1% house edge, 0.99 / 0.91123 = 1.0864, giving 1.08x in the example. A target of 2.00x would have lost.

Plinko

Each row uses one float. A common rule is floor(float x 2): 0 means the ball goes left, 1 means right. Count the right moves to find the landing slot, then look up the multiplier in the payout table for your row count and risk level. A 16-row game needs 16 floats, so it uses round 0 and round 1 of the HMAC.

Mines

The mine layout is a shuffle of the 25 tile positions. In a common implementation, the game starts with a list of positions 0 to 24 and, for each step i, picks floor(float x (25 - i)) as an index into the remaining list, removes that position and appends it to the shuffled order. The first N positions in the shuffled order are mines. Multiple HMAC rounds are used as needed.

Step 7: compare

Compare your recomputed result with the casino's bet record. For dice and limbo, compare the number. For plinko, compare the slot. For mines, compare the mine positions shown after the round.

Reading a mismatch

Most mismatches come from inputs, not fraud. Check in this order:

  1. Nonce off by one. Some casinos start at 0, some at 1.
  2. Wrong client seed. If you changed it mid-session, earlier bets used the old one.
  3. Wrong seed pair. Make sure the revealed server seed belongs to the period of the bet.
  4. Game settings. Plinko rows and risk, number of mines.
  5. Different scheme. The casino may use a different message format, byte conversion or formula. Read its documentation.

If all inputs are correct, the casino documents the common scheme, and the result still does not match, keep screenshots of the bet, seeds and documentation and contact the casino. Please also send us the details through the feedback form below.

Limits to keep in mind

  • Verification proves results followed the committed seeds and formula. It does not change the house edge.
  • It applies only to games built on the scheme. Third-party slots and live games are outside it.
  • Multiplayer games such as crash often use a shared hash chain instead of your seeds. Use the casino's own verification instructions for those.

Verifying in code

If you prefer to check without any website, this Node.js snippet implements the common scheme. It prints the SHA-256 hash of the server seed, the first float, and the dice roll for the worked example above.

const crypto = require('crypto');

function floats(serverSeed, clientSeed, nonce, count) {
  const out = [];
  for (let round = 0; out.length < count; round++) {
    const h = crypto.createHmac('sha256', serverSeed)
      .update(`${clientSeed}:${nonce}:${round}`)
      .digest();
    for (let i = 0; i < 32 && out.length < count; i += 4) {
      out.push(h[i] / 256 + h[i + 1] / 256 ** 2 + h[i + 2] / 256 ** 3 + h[i + 3] / 256 ** 4);
    }
  }
  return out;
}

const serverSeed = '5f3c9a1e7b2d4c6f8a0e1b3d5c7f9a2e4b6d8c0f1a3e5b7d9c2f4a6e8b0d1c3f';
const hash = crypto.createHash('sha256').update(serverSeed).digest('hex');
const [f] = floats(serverSeed, 'my-client-seed', 0, 1);
const dice = Math.floor(f * 10001) / 100;
console.log(hash, f.toFixed(5), dice);

Change the seeds and nonce to your own values. For other games, request more floats and apply the casino's documented formula. If the casino's documentation differs from this scheme, follow the documentation.

Keeping a verification log

If you play regularly, keep a simple log for each seed pair: the hashed server seed and the date you recorded it, your client seed, the revealed server seed, the range of nonces used, and the bets you verified. It takes a minute and gives you evidence if you ever need to raise a dispute.

Sources

Frequently asked questions

What do I need to verify a provably fair bet?
The revealed server seed, the hashed server seed shown before play, your client seed, the nonce, and the game settings.
Why does my verification not match?
The usual causes are an off-by-one nonce, the wrong client seed or seed pair, wrong game settings, or a casino scheme that differs from the common one.
Can I verify bets before rotating my seed?
No. The active server seed is secret until you rotate.
How many bets should I verify?
A random sample across games is a good check. Verifying any bet you are unsure about takes seconds.
Is the formula the same at every casino?
No. The HMAC approach is common, but game formulas and details differ. Check the casino's documentation.