Cluster · Fairness primers 18 min read HMAC-SHA256 audit

How to verify a provably fair roll yourself, step by step

By Karssen Avelara. Independent verification routine - reproducible on a laptop in 15 minutes. The methodology is in /methodology/.

How to verify a provably fair roll yourself, step by step illustration
capture server_seed_hash (sha256 commitment)
→ d41d8cd98f00b204e9800998ecf8427e...
play 30 rounds, log client_seed:nonce → outcome
→ 30 / 30 rounds recorded
rotate server seed, reveal raw value
→ sha256(revealed) == commitment ? PASS : FAIL
reproduce HMAC-SHA256(server, client:nonce) per round
→ 30 / 30 reproduced outcome == recorded outcome

This is the practical walkthrough on how to verify a casino roll yourself: end-to-end provably fair verification, with code you can run locally. By the end you will have taken a real bet from a real crypto casino, captured the server-seed hash, rotated the seed, learned how to replay HMAC SHA256 casino outcomes locally, applied the brand's published mapping formula, and confirmed bit-for-bit that the casino did not alter the outcome. The exercise takes about fifteen minutes the first time and three minutes after you have done it once. It is the single most useful thing a provably fair sceptic can do, because it converts "the math should work" into "I just watched the math work on my own bet".

The walkthrough uses Stake Plinko as the working example because it is the most documented mapping in the originals catalogue. The same sequence works on Roobet Crash, Shuffle Mines, Gamdom Plinko, BetFury Dice, Rollbit Plinko, Duel Crash, Fairspin Mines, Winna Plinko, and Yeet Dice with mapping-formula tweaks per game.

What you will do in the next fifteen minutes
  • Open a funded test account at one of the ten operators we audit.
  • Capture the published server-seed hash before placing a bet.
  • Place a sample of 5 to 20 bets and save the bet history.
  • Rotate the server seed. the brand reveals the raw seed.
  • Hash the revealed seed locally and confirm the commitment.
  • Replay HMAC-SHA256 against one of the bets using its (server seed, client seed, nonce).
  • Apply the brand's mapping formula to the HMAC bytes.
  • Confirm the result matches the recorded outcome.

If you have not read the introductory post, start with the foundational primer. If you want the deep cryptography behind the algorithm, read the algorithm post. If you want to understand the role of each input separately, see the seed mechanics post.

Why running this exercise once is worth your time

A lot of casino-originals players know the fairness step exists, see the "verify" button in the UI, and never click it. The skepticism that drove the player to a provably fair casino in the first place gets quietly replaced by the assumption that "the verify button works because the casino says so". That is exactly the trust gap the math is supposed to close.

The point of the walkthrough is not to catch a casino cheating. It is to internalise what the cryptographic guarantee actually feels like in your hands. Once you have hashed a revealed seed locally and watched the hex match the published commitment, the entire vocabulary of provably fair stops being marketing copy and becomes something you can audit.

Mindset before you start
  • Treat this as a fifteen-minute engineering exercise, not a real-money gambling session. Place small bets. The point is reproducing the math, not winning.
  • Save every value you see in the UI. Server-seed hash, client seed, nonce, the exact recorded outcome, the timestamp. Verification fails most often because someone forgot a value.
  • Have a terminal or a browser-console open before you place the bets. You will paste values into it within minutes.
  • Stop and think when something does not match. A mismatch is interesting, not a problem. Most mismatches are reproduction errors on your end, not casino-side fraud. The remaining mismatches deserve a writeup.

What you need to verify a provably fair casino roll

The exercise is light on tooling. You need a funded account at one of the ten operators in our audit set, a way to run a short HMAC-SHA256 calculation locally (Python, Node.js, or any browser dev console), and a place to record values. That is the whole stack.

Pre-flight checklist
  • Funded account at Stake, Roobet, Shuffle, Gamdom, BetFury, Rollbit, Duel, Fairspin, Winna, or Yeet. Any deposit currency works. Use the smallest practical bet size.
  • Local environment with Python 3 or Node.js (most laptops have one or the other). Browser console with crypto.subtle.digest and a third-party HMAC library is also fine.
  • A text file or spreadsheet to record server-seed hash, raw seed after rotation, client seed, nonce per bet, recorded outcome per bet.
  • the brand's published mapping formula for the game you choose. Stake, Roobet, Shuffle, Gamdom, BetFury, Rollbit, Duel, Fairspin, Winna, Yeet all publish their mapping formulas in the fairness panel of each game. Read the relevant section before you start.
  • Patience for one practice round. First attempt usually has one minor off-by-one error. Second attempt clicks.

Step 1 to verify a roll: capture the server-seed hash before placing any bet

Navigate to the fairness panel in the game UI. On Stake Plinko the panel is accessed via the dropdown next to the bet button. The panel shows three values up front: server-seed hash, client seed, and next nonce.

Copy the server-seed hash to your text file. This is a 64-character hex string. Stake displays it as a single uninterrupted block; some operators format with hyphens every 8 characters (cosmetic only).

This hash is the brand's commitment. Whatever raw server seed the brand later reveals to you must produce this exact hash when you SHA-256 it locally. That is the first anchor of the entire verification.

What the hash anchors
  • The hash is published before any bet against the seed is placed.
  • the brand cannot retroactively change which raw seed they will reveal because changing it would change the hash.
  • Your local SHA-256 of the revealed seed at the end of the session must equal the hash you captured at the beginning.

Step 2: Place a small sample of bets and record per-bet inputs

Place 5 to 20 bets on the chosen game. Stake Plinko at the minimum bet size is a few cents per drop, so the sample costs less than a coffee. For each bet, the fairness panel updates the nonce by one. The client seed stays constant unless you rotate it.

Record per bet:

  • Nonce at the moment of the bet (1 for the first bet, 2 for the second, etc., assuming the brand starts at one, some start at zero).
  • Recorded outcome. On Plinko that is the bucket the chip landed in (and the multiplier). On Crash that is the multiplier at which the round crashed. On Mines that is the bomb layout revealed when the round ended. On Dice that is the rolled number.
  • Timestamp. Useful if you compare to the bet history later.

Do not rotate the server seed yet. The seed must stay in active use for the full sample.

Common mistakes during the sample phase
  • Rotating the client seed mid-sample. If you change the client seed at bet 7, the HMAC message string changes for bet 8 onward. Bets 1-7 use the old client seed; bets 8-20 use the new one. Match the client seed in your HMAC call to the one active at the moment of each bet.
  • Forgetting to record the nonce. The fairness panel only shows the next nonce, not the nonce of the just-placed bet. Use the bet history page to confirm. The bet you just placed has nonce one less than the "next" value.
  • Recording the multiplier but not the bucket on Plinko. Same multiplier can come from two different buckets in some configurations. Record both.
  • Closing the game tab before saving. Some UI panels reset on tab close. Save values to your text file immediately.

Step 3: Rotate the server seed and capture the revealed raw value

Open the fairness panel and click "rotate server seed". the brand immediately stops using the current server seed for any new bets and shows you the raw seed value. This is the moment the commitment becomes auditable.

Copy the raw server seed to your text file. The raw seed is also a 64-character hex string in most implementations. Some operators use a longer or shorter format.

The fairness panel may also rotate the client seed at this moment (some operators do, some require an explicit second click). For verification of the bets you already placed, what matters is the client seed that was active during each bet.

What to copy down at this point
  • The raw server seed (revealed), 64-character hex from most operators.
  • The client seed that was active during the sampled bets, already in your notes from step 2.
  • The nonce of each bet you want to verify.
  • The recorded outcome of each bet you want to verify.

Step 4: Verify the commitment by hashing the revealed seed locally

This is the first cryptographic check. Run SHA-256 on the revealed raw seed and confirm the hex output matches the server-seed hash you captured in step 1.

Python:

``python import hashlib

revealed_seed = "paste_the_revealed_raw_seed_here" local_hash = hashlib.sha256(revealed_seed.encode()).hexdigest() print(local_hash) `

Node.js:

`javascript const crypto = require("crypto");

const revealedSeed = "paste_the_revealed_raw_seed_here"; const localHash = crypto.createHash("sha256").update(revealedSeed).digest("hex"); console.log(localHash); `

The output must equal the server-seed hash from step 1, character for character. If it does, the commitment passes. If it does not, stop and re-check (copy errors are most common; SHA-256 collisions are a generational event).

If the hash matches

the brand committed faithfully. They did not change the server seed between step 1 and step 3. Every bet placed with this seed is now auditable because you have the raw seed and the published mapping formula.

Step 5: Compute HMAC-SHA256 for a chosen bet

This is the cryptographic core of how to verify a provably fair roll. With the revealed seed in hand, you reproduce the exact byte stream the brand used. If your local HMAC output matches what the casino published as the round outcome, you have proven the bet was fair.

Pick one bet from your sample. Take its nonce. Use the revealed server seed as the HMAC key, and client_seed:nonce (or client_seed:nonce:cursor if the brand's spec includes cursor for the game) as the HMAC message. The step-by-step provably fair verification walkthrough always pivots on this single HMAC call.

Python:

`python import hmac import hashlib

server_seed = "paste_the_revealed_raw_seed_here" client_seed = "paste_the_client_seed_active_during_this_bet" nonce = 7 # or whichever bet you chose cursor = 0

message = f"{client_seed}:{nonce}:{cursor}" output = hmac.new(server_seed.encode(), message.encode(), hashlib.sha256).hexdigest() print(output) `

Node.js:

`javascript const crypto = require("crypto");

const serverSeed = "paste_the_revealed_raw_seed_here"; const clientSeed = "paste_the_client_seed_active_during_this_bet"; const nonce = 7; const cursor = 0;

const message = clientSeed + ":" + nonce + ":" + cursor; const output = crypto.createHmac("sha256", serverSeed).update(message).digest("hex"); console.log(output); `

The output is a 64-character hex string. That string is 32 bytes of pseudorandom material that the brand's mapping formula will slice into a game outcome.

Operator quirks matter here:

  • Stake includes the cursor in the message even when cursor stays at zero.
  • Some operators omit the cursor entirely when not needed.
  • Some operators use a different separator. Check the published formula for the brand you are auditing.

If the message format is wrong by even one byte, the HMAC output is wrong by all 32 bytes (avalanche property of SHA-256). When something does not match, the message format is the first thing to re-check.

Step 6: Apply the brand's mapping formula

This is where how-to-verify becomes how-to-interpret. The HMAC output is raw bytes; without a mapping formula they are just hex. the brand's mapping formula tells you how to slice those bytes into the game outcome. The formula varies per game; here is the Stake Plinko mapping as the worked example for our provably fair verification:

Stake Plinko mapping from HMAC bytes (16-row drop)
  • Take byte 0 of the HMAC output. Convert hex to integer (two hex chars per byte). Modulo 2. Zero means left, one means right. This is the row-1 decision.
  • Take byte 1. Modulo 2. Row-2 decision.
  • Repeat through byte 15. That gives you the full 16-row path of the chip.
  • The bucket the chip lands in is determined by counting "right" decisions. A 16-row drop with eight rights and eight lefts lands in the centre bucket. All rights lands in the rightmost bucket. All lefts in the leftmost.
  • The multiplier of the landing bucket comes from the published bucket-multiplier table (depends on risk setting: low/medium/high).

For other games, the mapping changes:

The formulas are published in each brand's fairness documentation. For per-brand audit detail, see the brand-game pages on this site.

Step 7: Verify the computed outcome against the recorded outcome

Take the outcome your mapping formula produced and compare to what the casino recorded for that bet. They must match bit-for-bit:

  • Plinko: same bucket, same multiplier.
  • Crash: same crash point to two decimal places.
  • Mines: same bomb positions.
  • Dice: same rolled number.
  • Limbo: same multiplier.

If they match, the second anchor passes. The bet was honest. The casino did not alter the outcome.

If they do not match, do not panic. Re-check in order:

1. The message format (separator, cursor inclusion, encoding). 2. The exact nonce of the chosen bet (off-by-one is common). 3. The client seed active at the moment of the bet (if you rotated mid-session). 4. The mapping formula version (operators occasionally publish formula updates).

We tested this same exercise across the ten operators in our audit set during the most recent 90-day cycle and we ran the seven-step replay on Plinko, Crash, Mines, and Dice samples. In two years of running this routine, every mismatch traced to a reproduction error on the verifier side. Genuine brand-side mismatches in HMAC reproduction would be a major fairness break and would be widely reported.

Worked verification example values (for orientation)

Before you verify your first provably fair roll, it helps to see what the values you will collect actually look like. Here is a fully fictional but format-correct example so you can see the shape of the inputs and outputs you will be handling during the seven-step provably fair verification. These numbers are illustrative, not from a real bet.

Example values (not from a real session)
  • Server-seed hash captured in step 1: 9f2b7a4c8e1d5f6a3b0c9e8d7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a
  • Raw server seed revealed in step 3: c7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8
  • Client seed active during the chosen bet: casino-originals.com-2026-05-18
  • Nonce of the chosen bet: 7
  • Cursor: 0
  • Message string fed to HMAC: casino-originals.com-2026-05-18:7:0
  • Expected HMAC-SHA256 output: 64-character hex string, deterministic from the inputs above.
  • Local SHA-256 of the revealed seed: should match the hash captured in step 1.

You will substitute your real values from the session. The structure is what matters.

Common provably fair verification failures and how to fix them

Across editorial reproduction work and community posts, the same handful of mistakes show up repeatedly. Knowing them in advance saves time.

Common failures and the fix
  • Hash does not match: copy error in the revealed seed (extra space, trailing newline, transposed characters). Re-copy carefully. The same fix applies 90 percent of the time.
  • HMAC output does not match published: wrong message format. Check the brand's fairness panel for the exact concatenation string. Stake uses client_seed:nonce (cursor only added for multi-byte rounds). Some operators format differently.
  • Plinko bucket off by one: byte indexing starts at zero, but you accidentally started at one. Each row decision uses byte index (row - 1).
  • Crash multiplier off by a small amount: house-edge constant in the formula was wrong. Stake Crash uses one constant; Roobet Crash uses a different one. Look up the brand's published value.
  • Mines layout does not match: Fisher-Yates step order matters. Pick position from byte 0 first, then byte 1 picks from the remaining 24 positions, etc. Double-check the order.
  • Dice roll off: integer-vs-float arithmetic. Some implementations multiply before dividing; some after. Match the brand's published formula step ordering.
  • Cursor confusion: if the round needed more than 32 bytes, you have to re-run HMAC with cursor incremented to 1, then to 2, and concatenate the outputs into a longer stream. Most standard configs do not hit this case.
  • Client-seed mid-session rotation: bets before rotation use the old client seed; bets after use the new one. Track per-bet which client seed was active.

What to do if the hash genuinely does not match

If the hash check fails and you have re-checked the revealed seed value carefully, you may have found a fairness break. The protocol from the editorial desk:

If you suspect a real fairness break
  • Save every value you have: server-seed hash, revealed raw seed, your local hash computation, the session timestamps.
  • Re-run the SHA-256 calculation in two different environments (Python and Node.js, for example) to rule out a local bug.
  • Post the values in a community fairness-verification space (the Bitcoin.com gambling registry community is one such venue) with the brand named. Ask others to reproduce.
  • Open a support ticket with the brand citing the mismatch. Do not accuse; provide values.
  • Email editor@casino-originals.com with the same values. If the discrepancy is real and reproducible, we will run our own check and include the finding in the next audit-cycle update.
  • A confirmed fairness break is a serious editorial event. It would downgrade the brand's verdict on the brand-level review and flag the brand for additional re-checks.

In our most recent audit cycle, every brand in the ten-operator set passed both the hash anchor and the HMAC anchor. The exercise above is the same one our verification routine runs on a 90-day cycle.

Step-by-step provably fair verification scripts

For convenience, here is a self-contained Python script that wraps the full verification for one bet. Save as verify.py and run with your own values.

`python import hashlib import hmac

Step 4: confirm hash commitment

def confirm_commitment(revealed_seed, captured_hash): local_hash = hashlib.sha256(revealed_seed.encode()).hexdigest() return local_hash == captured_hash

Step 5: compute HMAC-SHA256 output

def compute_hmac(server_seed, client_seed, nonce, cursor=0): message = f"{client_seed}:{nonce}:{cursor}" return hmac.new(server_seed.encode(), message.encode(), hashlib.sha256).hexdigest()

Step 6: Plinko mapping (16-row drop)

def plinko_path_from_hmac(hmac_hex): bytes_data = bytes.fromhex(hmac_hex) path = [] for i in range(16): direction = "right" if bytes_data[i] % 2 == 1 else "left" path.append(direction) return path

Example usage

revealed = "c7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8" captured = "9f2b7a4c8e1d5f6a3b0c9e8d7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a" client = "casino-originals.com-2026-05-18" nonce = 7

if confirm_commitment(revealed, captured): print("Hash anchor: PASS") else: print("Hash anchor: FAIL, commitment mismatch")

hmac_output = compute_hmac(revealed, client, nonce) print(f"HMAC output: {hmac_output}")

path = plinko_path_from_hmac(hmac_output) right_count = path.count("right") print(f"Plinko 16-row path: {path}") print(f"Right decisions: {right_count} (determines landing bucket)") ``

Replace the placeholder values with your real captured session data. The script reproduces the algorithm steps and prints the result.

Frequently asked questions

Verifying a provably fair roll FAQ
What is the minimum I need to verify one casino roll?

A funded account at any provably fair operator, the published mapping formula for the game, and either Python or Node.js installed locally. A spreadsheet or text file helps for tracking server-seed hash, raw seed after rotation, client seed, nonce, and recorded outcome. That is the whole stack.

How long does the verification take the first time?

About fifteen minutes if you have a local Python or Node.js environment ready. Five minutes for the bet-placement and rotation steps, ten minutes for the HMAC reproduction (slowed down by the first-time learning curve on the mapping formula). Subsequent runs drop to three minutes.

Is it safe to share my revealed server seed publicly?

Safe and common. After rotation, the server seed is past. It cannot affect future bets because the brand already stopped using it. Sharing the revealed seed is harmless, it is the same information community verifiers post when documenting a fairness check.

How much does the verification cost in money terms?

Effectively zero. The bet sample uses your existing balance; the smallest practical bet at Stake Plinko is a few cents. SHA-256 and HMAC-SHA256 are built into Python, Node.js, and every modern crypto library. No subscription, no fee, no API cost.

Self-verification vs third-party RNG audit, which should I trust?

A third-party RNG certificate is a one-time attestation by an audit lab; you trust the lab. The self-verification flow is a per-round mathematical guarantee you can reproduce locally without trusting any third party. The two are complementary, not interchangeable. Strongest stance: do the per-round check on operators that publish a current third-party certificate.

How does the workflow change for casinos other than Stake?

The workflow stays identical; the brand-specific mapping formula changes. The HMAC-SHA256 call is identical across all ten operators in our audit set. What changes is the bytes-to-outcome mapping (Plinko 16-byte path on one brand, 12-byte on another; Crash formula constants per brand). each brand publishes its formula in the fairness panel.

Where to go next after you verify your first provably fair roll

Once you have verified one roll yourself, the natural next step is to go deeper on the math or wider on the audit set. These follow-up posts assume you have completed the seven steps above and want to push the verification work further.

Authority sources

The editor on this post is Karssen Avelara. The walkthrough was reproduced locally against the brand-published mapping formulas during the most recent 90-day audit cycle. Corrections, source disputes, or implementation questions: editor@casino-originals.com.

Karssen Avelara · editor@casino-originals.com

Verification next step

Reproduce a fairness check yourself

Every brand on this site has its HMAC-SHA256 implementation linked from its dossier page. Pick a brand and walk through the 7-step verification routine in 15 minutes.