Every result on Grand Salon Club is decided on our server by a provably fair random number generator. We commit to our secret before you bet, you can add your own randomness, and afterwards you can recompute any result yourself. Neither we nor you can change a result once the bet is placed.
How results are made
- Before you play, we create a random server seed and show you its SHA-256 hash. The hash commits us to the seed without revealing it.
- Your client seed is mixed in. We pick a random one for you; you can replace it with your own at any time.
- A nonce counts your rounds with the current seed pair: 1 for the first round, 2 for the second, and so on.
- Each round's random numbers are derived only from the server seed, client seed and nonce, so the outcome is fixed the moment you place the bet. The game in your browser only animates the result our server sends back.
- When the seed pair is rotated, the old server seed is revealed so you can check every round played with it against the hash you were shown.
Seeds and nonce
- Your current server seed hash and nonce are shown under the bet panel in every game.
- The seed pair rotates automatically after 1,000 rounds, and whenever you set a new client seed. Setting a client seed therefore also reveals your previous server seed.
- While logged in you can read your current hash, client seed and nonce, plus the most recently revealed seed pair, at
GET https://grandsalonclub.com/api/casino/fairness, and set a new client seed (letters and digits, up to 64 characters) withPOST https://grandsalonclub.com/api/casino/fairness. Note down a revealed seed if you want to verify it later: only the latest one is shown.
From hash to result
Random numbers are read from this stream of HMAC-SHA256 blocks, keyed with the server seed:
HMAC-SHA256(key = server_seed, message = "client_seed:nonce:cursor")
cursorstarts at 0. Each 32-byte block gives eight numbers; when they are used up, the cursor goes up by one and the next block is computed.- Each number takes the next 4 bytes as an unsigned big-endian integer and divides it by 232, giving a value from 0 (inclusive) to 1 (exclusive).
- Whole numbers in a range, such as a card or a roulette pocket, are
min + floor(value × (max − min + 1)). - Each game turns these numbers into its outcome — a dice roll, a card, a mine position, a crash point — with a fixed rule. The same seeds and nonce always give the same result.
Verifying a round
- Note the server seed hash, your client seed and the round's nonce.
- After the seed pair is rotated, take the revealed server seed and check that its SHA-256 hash equals the hash you were shown.
- Recompute the first random number of the round, for example in a browser console:
const key = await crypto.subtle.importKey('raw', new TextEncoder().encode(serverSeed),
{ name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
const block = new DataView(await crypto.subtle.sign('HMAC', key,
new TextEncoder().encode(`${clientSeed}:${nonce}:0`)));
const first = block.getUint32(0) / 2 ** 32; // next numbers: offsets 4, 8, … 28
Return to player
Payout multipliers in every game are set so that, over a very large number of rounds, a game returns about 98% of the Coins wagered (a house edge of 2%). This is a long-term average: in any single session you can win or lose far more. Coins won are virtual and have no cash value.