Loading Mazal

Play with 2× your deposit - 100% up to $500No KYC · No ID · No email verifyInstant DepositsInstant Withdraws
100% DEPOSIT MATCH · UP TO $500 · NO KYCCLAIM
PROVABLY FAIR · LOCKED v1.0.0

Every roll, verifiable.

We commit to the result before you bet, reveal the secret after you settle, and publish the exact algorithm so anyone can recompute the roll. We can't change the outcome after seeing your bet — the math doesn't let us.

spec v1.0.0 · published 2026-05-23

The 30-second version

  1. Before any round, we generate a random 32-byte server_seed and publish its SHA-256 hash. The hash is locked in — we can't change the seed without changing the hash.
  2. You contribute a client_seed (anything you want — a phrase, random bytes, your dog's name).
  3. The roll is HMAC-SHA256(server_seed, “client_seed:nonce:round_index”), mapped to a number in [0, 1).
  4. After the round, we reveal server_seed. You hash it yourself: if it matches the published hash, the seed is authentic. Then you recompute the roll with the same formula and confirm the result.

Why this can’t be cheated

A house that wants to cheat needs to look at your bet, then change the outcome. With commit/reveal that's impossible:

  • The server_seed is fixed before your bet — its SHA-256 is already published.
  • Your client_seed is yours. The house can't pick it.
  • HMAC-SHA256 is one-way. There's no server_seed that produces a specific desired roll without breaking SHA-256 itself.
  • The reveal proves the seed matches the commit. You verify with one hash function.

The exact algorithm

This is the entire roll function. It's what the server runs. No randomness lives outside this — every game (dice, coinflip, plinko, mines, roulette, blackjack, baccarat) calls rollFloat with a different nonce.

// HMAC-SHA256(server_seed) of "client_seed:nonce:round_index"
// First 8 bytes → uint64 → divide by 2^64 → uniform in [0, 1)
function rollFloat(serverSeed, clientSeed, nonce, roundIndex = 0) {
  const mac = createHmac('sha256', serverSeed)
    .update(`${clientSeed}:${nonce}:${roundIndex}`)
    .digest();
  let n = 0n;
  for (let i = 0; i < 8; i++) n = (n << 8n) | BigInt(mac[i]);
  return Number(n) / Number(1n << 64n);
}

For games that pick from a weighted list (roulette wheel, card draw), we multiply rollFloat by the sum of weights and walk the list. Deterministic for the same inputs.

Worked examples: roll → outcome

One roll, three games. Each rule below is structural and fixed — it depends only on the verifiable roll, never on our return-to-player settings. The roll → outcome step is exactly what provably fair guarantees, and it is identical for every player. You can reproduce all of this: paste the seeds into the verifier below with nonce 0 and round_index 0 and you'll get the same roll.

server_seed: 3f9a1c0e7b2d4856a1f0c3e9b7d2840f5e6a1b2c3d4e5f60718293a4b5c6d7e8
sha256(server_seed): 7698495f8eda1cac4bc88402ad43e70ecebd6506d401fddf1c14cd64dfbf6a4e

The published rules:

  • Coin fliproll < 0.5 → Heads, else Tails (a clean 50/50).
  • Dicefloor(roll × 10000) / 100 → your number in 0.00–99.99.
  • Roulettefloor(roll × 37) → pocket 0–36 (single-zero wheel).
client_seed = table-7roll = 0.280901844264620
Coin flip
Heads
Dice
28.09
Roulette
pocket 10
client_seed = spin-itroll = 0.689490098995691
Coin flip
Tails
Dice
68.94
Roulette
pocket 25

What a win pays is a separate step: each game multiplies your stake by the payout shown up front on that game's page. The fairness guarantee here is about the outcome — that the number wasn't tampered with — and these examples prove it without exposing any house configuration.

Verify a roll yourself

Paste a revealed server_seed from any of your settled bets along with your client_seed and the round's nonce. The verifier below runs the same code as the server, in your browser.

Verify the seed itself

Before the reveal, you only see sha256(server_seed). After the reveal you can hash the seed yourself:

# Bash
echo -n "<revealed_server_seed>" | shasum -a 256

# Python
import hashlib; print(hashlib.sha256(b"<revealed_server_seed>").hexdigest())

# Node
require('crypto').createHash('sha256').update("<revealed_server_seed>").digest('hex')

If the output matches the hash that was published before your bet, the seed is real. Then run it through the verifier above to confirm the roll.

What this doesn’t cover

Provably fair only covers roll generation — that the random number used in your game wasn't tampered with. It does not prove:

  • Game logic. That the verified roll was mapped to the right payout. Every game shows its payout multipliers up front (see the worked examples above for the roll → outcome step).
  • Solvency. That the house can pay out. That's a regulatory / financial question, not a cryptographic one.
  • The reveal happens. A house that never reveals can't be verified. Mazal reveals seed every round you settle.

Spec lock

The algorithm above is the entire spec. If we ever change it — even a comment — this page's version bumps and the reference implementation hash changes. There is no other code path. Bookmark this URL; it is the authoritative document.

spec version: 1.0.0
published: 2026-05-23
algorithm: HMAC-SHA256 commit/reveal