Provably Fair

Every shuffle is mathematically verifiable. No trust required.

The Protocol

  1. 1
    Before the round — the server generates a random 32-byte seed and publishes its SHA-256 hash (the commitment). You can verify this hash before any cards are dealt.
  2. 2
    You provide a client seed — any string of your choice, submitted before the round begins. This ensures the server cannot predict your input when it generated its seed.
  3. 3
    The shuffle seed is derived — using HMAC-SHA256 with the server seed as key and client_seed || nonce as data. Neither party alone controls the outcome.
  4. 4
    After the round — the server reveals the original seed. You verify SHA-256(seed) matches the commitment, re-derive the shuffle, and confirm every card dealt matches the audit transcript.

The Shuffle Algorithm

The shuffle uses Fisher-Yates (Knuth) with a counter-mode HMAC-SHA256 PRNG. Each random index is generated as:

random_bytes(i) = HMAC-SHA256(key: shuffle_seed, data: <<i::big-64>>)

The 32-byte result is decoded as a big-endian unsigned integer and reduced modulo the current range. The modulo bias is negligible — range ≤ 52, entropy = 2²⁵⁶.

Nonce

The nonce increments with each new round within a session. It ensures that even if you reuse the same client seed, each round produces a different shuffle. The nonce is visible in every audit transcript.

Algorithm Version

faro-shuffle-v1

The algorithm version is embedded in every audit transcript. Future algorithm changes will use a new version identifier, preserving the ability to verify historical rounds.

Verify Yourself

After a round, you can copy the revealed server seed, your client seed, and nonce from the audit panel and check them independently — here or using any HMAC-SHA256 and SHA-256 tool.

Provably fair · HMAC-SHA256 shuffle · All games verifiable on-chain