Compare

Provably fair explained: check the inputs and result

Provably fair lets you recalculate a completed game result from its revealed inputs. Save the server-seed hash before the round, then compare the disclosed seed with that hash and reproduce the outcome using the exact game's algorithm. Shuffle Dice's published example turns client seed abc, server seed def and nonce 1 into 43.05.

The useful question is whether the record agrees with the calculation. Getting a number from a checker is only part of that task: it must be the number for the same game, seed pair and completed bet. The commitment comparison also needs the hash that was available before the result.

What the commitment keeps fixed

A commitment puts a checkable hash in front of you while the value behind it remains hidden. Shuffle describes its active server seed as a random 64-character hexadecimal string and publishes a SHA-256 hash of that seed. The active secret is held back until the pair is replaced. Its client seed is the player's input, initially generated by the browser; its nonce counts bets made with the same pair, starting at zero.

A saved commitment and two checks after revelation Before the result save the server-seed hash. Keep the completed bet and old inputs together. After replacing the pair reveal the old server seed. Compare its hash with the earlier record and separately recalculate that game's outcome. Before the resultSave the server-seed hashKeep it with the old pair Completed betKeep result, client seed, nonceand the matching game rules Replace the pairThe old server seed is revealedNew pair belongs to later bets Make two comparisonsRevealed seed → earlier hashOld inputs → recorded result
Keep the timing record and outcome record together. The two comparisons answer different questions.

After a completed game, replacing the pair reveals the previous server seed. You can then make two separate comparisons:

Does the revealed seed agree with the earlier hash?

Apply the implementation's commitment-hash calculation to the revealed value and compare it with your saved hash. A match ties those values together under that representation. The timing matters: a hash first shown after a result cannot establish that it was committed beforehand.

Do those inputs reproduce the recorded outcome?

Use the old server seed, old client seed and that bet's nonce in the matching game's calculation. Compare the calculated result with the completed record. This comparison can work even if you did not save an earlier commitment, but it then answers only the outcome-reproduction question.

The word "unhash" in Shuffle's instructions means revealing the stored old seed. It does not mean decrypting SHA-256 or recovering a secret by reversing its hash. A visible server-seed hash is not the secret HMAC key required for the Dice calculation.

Keep the old bet and its inputs together

A current seed panel can belong to the next pair. Start from the completed bet you want to check and keep its identity, result and inputs in one record. The labels have different jobs:

Input
Earlier Server Seed hash
What it does in the Shuffle example
The commitment to compare after revelation
What to preserve
The complete hash saved before the result, linked to the old pair
Input
Revealed Server Seed
What it does in the Shuffle example
The key for the HMAC-SHA256 outcome calculation
What to preserve
The previous seed, exactly as revealed; a hash cannot replace it
Input
Client Seed
What it does in the Shuffle example
The player's text input to the message
What to preserve
The text attached to the completed bet, including its case and any spaces
Input
Nonce
What it does in the Shuffle example
Identifies the bet within that seed pair
What to preserve
The completed bet's counter, not the counter for a later bet
Input
Cursor
What it does in the Shuffle example
Selects bytes from the generated stream
What to preserve
0 for the first Dice output used here; other games can consume different bytes
Input
Game and output mapping
What it does in the Shuffle example
Converts generated data into the game's result
What to preserve
The precise implementation and the rules that turn its output into a roll

Use the same representation the implementation uses. A string that looks hexadecimal can be treated as literal text or decoded into binary bytes; those are different inputs. The Dice HMAC example uses the literal seed string. For an actual commitment comparison, use the matching commitment code or verifier to preserve that implementation's representation.

Reveal and check a completed Shuffle Dice bet

Shuffle's verification instructions give the following path. They describe the product controls; the calculations here use published examples, not a submitted player bet.

  1. Save the completed record. Keep the bet identifier, game, displayed result, Client Seed and Nonce. Keep the earlier Server Seed hash too if you saved it before that result.
  2. Finish existing games before replacing the pair. Open the bet modal and select Rotate pair. Enter the desired next Client Seed, then select Change. That next seed belongs to the new pair.
  3. Return to the old bet. Close the fairness modal and reopen the completed record. Its previous Server Seed is now revealed. The old bet's Client Seed and Nonce stay the same.
  4. Compare the commitment separately. Hash the revealed old value using the matching implementation's representation, or use its matching commitment verifier. Compare with the saved earlier hash. Without that earlier record, leave the timing comparison unresolved.
  5. Select Verify for the matching game. Use the old bet's Client Seed, revealed Server Seed and Nonce. An independent calculation must also use that game's byte selection and result mapping.
  6. Compare with the bet slip. Record the calculated result and the result being checked. Distinguish a match, a completed comparison that disagrees, and a check that cannot yet be completed because an input is missing.

An online verifier may require account access. Login or loading a page is not a completed verification; the check needs the old inputs and a comparison with their recorded result. You can practise the arithmetic with the complete published vector without creating a betting record.

Reproduce 43.05 from Shuffle's published Dice example

These are illustrative inputs published for Shuffle Dice: Client Seed abc, Server Seed def, Nonce 1, Cursor 0, and one output. The short seed def is a teaching example, not the 64-character operational format or a player's disclosed secret. The expected Dice result is 43.05.

Build the exact HMAC message

The first output uses block index zero. HMAC-SHA256 takes the literal text def as its key and the literal message abc:1:0. The colons separate Client Seed, Nonce and block index. The final zero is the block index, not a second bet counter.

Stage
HMAC key
Exact value
def as literal text
Stage
HMAC message
Exact value
abc:1:0
Stage
Message bytes in hexadecimal
Exact value
6162633a313a30
Stage
HMAC-SHA256 digest
Exact value
6e37d85daa228fdf2caeabc192b01502d99bc5e4433994bcabac23403bf407a5

SHA-256 produces 32 bytes, or 256 bits. Each pair of hexadecimal digits represents one byte. Take the first four bytes of that digest: hexadecimal 6e 37 d8 5d, which is decimal 110, 55, 216, 93.

Turn four bytes into the float

Read those bytes in big-endian order, with the first byte carrying the greatest weight. The unsigned integer is 1,849,153,629. Divide it by 4,294,967,296, which is 2 raised to the power 32:

q = 110 × 256³ + 55 × 256² + 216 × 256 + 93
q = 1849153629
u = q / 4294967296
u = 0.43053962965495884

The equivalent byte-by-byte calculation is:

u = 110/256 + 55/65536 + 216/16777216 + 93/4294967296

This conversion produces a value from zero inclusive to one exclusive. It does not by itself give a Dice roll, a crash multiplier or a playing card. The game's mapping supplies that next step.

Apply the Dice mapping without early rounding

Shuffle Dice uses floor(u × 10001) / 100. The floor operation discards the fractional part before division by 100. With the full float:

floor(0.43053962965495884 × 10001) / 100 = 43.05

The displayed result range is 0.00 to 100.00, with 10,001 possible displayed values. That count is a range description, not evidence that every displayed value has exactly the same probability. Keep the full intermediate value for the calculation; rounding it first can change the result.

Run the same calculation offline

This small Python example uses the standard library and produces the published digest and roll. It is an adaptation of the published one-output calculation with the scalar and byte order made explicit.

import hashlib
import hmac
import math

server_seed = "def"
client_seed = "abc"
nonce = 1
cursor = 0
block_index = cursor // 32
byte_offset = cursor % 32
message = f"{client_seed}:{nonce}:{block_index}"
digest = hmac.new(
    server_seed.encode("utf-8"),
    message.encode("utf-8"),
    hashlib.sha256,
).digest()
first_four = digest[byte_offset:byte_offset + 4]
q = int.from_bytes(first_four, "big")
u = q / 4294967296
roll = math.floor(u * 10001) / 100
print(digest.hex())
print(list(first_four))
print(q)
print(u)
print(f"{roll:.2f}")

Expected output:

6e37d85daa228fdf2caeabc192b01502d99bc5e4433994bcabac23403bf407a5
[110, 55, 216, 93]
1849153629
0.43053962965495884
43.05

The example calculates the first Dice result at Cursor 0. The general byte generator uses floor(cursor / 32) for the HMAC block and cursor mod 32 for its byte offset. Games consuming more outputs can continue through four-byte groups and subsequent blocks. This short script does not implement every game's cursor progression or events.

Producing 43.05 reproduces the published example. It supplies no earlier commitment record for def and says nothing about a paid or credited win. The wager's win condition and payout calculation are separate from generating its roll.

A synthetic commitment-and-reveal example

The following is an entirely artificial offline example. The seed is deliberately predictable: the text 0123456789abcdef repeated four times. It is chosen to make the two comparisons reproducible, not to model secure seed generation, an actual casino commitment or a played round. For this example only, the commitment is defined as SHA-256 of the literal UTF-8 seed text.

Part of the artificial record
Commitment kept before the illustrative result
Value and place in the sequence
a8ae6e6ee929abea3afcfc5258c8ccd6f85273e0d4626d26c7279f3250f77c8e
Part of the artificial record
Completed record compared afterwards
Value and place in the sequence
25.10; Client Seed casinosss-example; Nonce 7; Cursor 0
Part of the artificial record
Server Seed revealed for the later calculation
Value and place in the sequence
0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

Hashing that literal seed text with SHA-256 gives the commitment above. Repeating Shuffle Dice's outcome calculation with message casinosss-example:7:0 gives:

Calculation
HMAC-SHA256
Result
4046436370ad8d39075d58b218ccf9df4d63be108d55bb743837f9d39f53bf28
Calculation
First four bytes
Result
64, 70, 67, 99
Calculation
Unsigned big-endian integer
Result
1078346595
Calculation
Float
Result
0.2510721317958087
Calculation
Shuffle Dice mapping
Result
25.10

Both comparisons now agree within this constructed sequence: the revealed text hashes to the saved commitment, and the calculation produces the constructed 25.10 record. To reproduce it, replace the three seed/nonce values in the Python example. For the commitment comparison, calculate hashlib.sha256(server_seed.encode("utf-8")).hexdigest() separately.

The UTF-8 commitment rule is explicitly defined for this artificial example. Shuffle's commitment description names SHA-256 and a 64-character hexadecimal seed but does not specify the operational commitment's text-versus-decoded-byte representation. Use the actual implementation's commitment code or matching verifier for a real record; this example does not establish that deployed representation.

If your result does not match

Compare the earliest point where the calculations separate. A different message, digest, byte group or mapping can explain a different final number.

Change to the published example
abc, def, Nonce 1, Cursor 0
Calculated roll
43.05
What it demonstrates
The complete published baseline
Change to the published example
Use Nonce 2 with the same seeds
Calculated roll
13.41
What it demonstrates
A later counter checks a different input
Change to the published example
Use Client Seed abd, Server Seed def, Nonce 1
Calculated roll
99.10
What it demonstrates
One changed character changes this calculation

Those are specific counterexamples. Different inputs can still land on the same displayed roll because the output grid is finite; a coincidentally equal number is not a substitute for checking the full inputs and calculation.

Trace a disagreement in this order

  1. Record and game. Check the exact completed bet, its game and the algorithm version. A correctly calculated result for another bet does not resolve this one.
  2. Old pair. Use the old Client Seed and revealed old Server Seed. Keep the newly selected pair out of the calculation for the completed bet.
  3. Text and counters. Compare case, spaces, delimiters and the completed Nonce. Preserve seed text exactly; silently trimming or changing case changes the input. Uppercase and lowercase hexadecimal digest displays can represent the same bytes, which is a different issue from changing the seed text.
  4. Key encoding and byte selection. Check literal text versus decoded hexadecimal bytes, the HMAC block and Cursor. The synthetic 64-character key gives digest 4046436370ad8d39075d58b218ccf9df4d63be108d55bb743837f9d39f53bf28 as literal text; decoding that key into bytes gives 4ca6ba1c5309bd89562fddb0b36e19ecb0b3db9875b4bcb65e49e073f79b331d.
  5. Mapping and rounding. Apply the exact game's final transformation. In the published baseline, the expression u × 10001 / 100 before floor is approximately 43.0582683618; Shuffle's specified floor produces 43.05. A floor step, display rounding and settlement rounding have different meanings.

Shared terminology does not establish a shared algorithm. For example, the published Stake Dice expression shown as (float * 10001) / 100 does not contain Shuffle's floor operation. That expression alone cannot establish Stake's final display or settlement rounding. Adding a floor and calling the result a verified Stake roll would change the implementation being checked.

Missing inputs need a different next action

What is missing?
Earlier commitment
What you can still establish
A completed outcome may still be reproducible
What to do next
Keep the outcome comparison separate; an after-result hash cannot repair the missing earlier record
What is missing?
Revealed old Server Seed
What you can still establish
You cannot run the documented seed-keyed calculation yet
What to do next
Use the game's documented reveal procedure for the old completed record
What is missing?
Client Seed or completed Nonce
What you can still establish
The calculation is not tied to that bet
What to do next
Retrieve the old bet's values, rather than substituting the current panel's values
What is missing?
Exact game mapping or version
What you can still establish
A hash or float can be checked without establishing the final game result
What to do next
Obtain the matching calculation or verifier for that game and version
What is missing?
Access to the verifier
What you can still establish
The page's access state alone says nothing about an outcome
What to do next
Keep the completed record and inputs; a published matching algorithm can support an offline calculation

Missing data is an incomplete check. A failed comparison is a calculation made with identified inputs that disagrees with the identified record. Neither should be reported as the other.

If the mismatch remains after these checks, keep the bet or round identifier, game/version, earlier commitment, revealed old inputs, exact calculation, expected output and actual recorded result together when asking support to explain it. Show where the values diverge. A generic "fairness failed" message leaves out the information needed to reproduce the problem.

Aviator has its own verification path

Aviator's native rules describe a fly-away coefficient generated before the round. They place the settings at Game menu > Provably Fair settings. To inspect a completed round, use the fairness icon beside its result in My Bets or Top; the rules also describe the icon next to a result in History.

SPRIBE's provider-wide explanation places Next server seed SHA256 in the fairness settings and describes a completed-history window showing the Server Seed, players' seeds, combined hash and round result. Its outcome explanation combines server and player inputs with SHA-512. These field names and steps are the published workflow, not a reproduced Aviator coefficient.

The provider's illustrative AB and CD example hashes the combined text ABCD. Its displayed Mini Roulette result is 25.00, and its explanation says the final mathematics differs by game. That illustration does not supply Aviator's exact hash-to-crash mapping, client-selection count or nonce convention. Keep the complete Shuffle Dice example attached to Dice; it cannot calculate Aviator's next or previous crash coefficient.

For Aviator, keep the round identity and the fields displayed by its own completed-round check. Reproducing a coefficient independently additionally requires that exact game's published result mapping. The Aviator review explains its product controls and how the completed-round check fits them.

What a matching proof tells you about the game

A matching earlier commitment and a reproduced outcome provide evidence that the disclosed value and recorded result are consistent with the saved commitment, supplied inputs and stated calculation. Preserve that scope when judging a game or casino that uses the label.

Question
Was this disclosed seed consistent with the saved earlier commitment?
What the completed-round check answers
The commitment comparison answers this for the matching representation and saved record
Question
Do these inputs reproduce this outcome?
What the completed-round check answers
The game-specific calculation and comparison answer this
Question
Were the seeds generated with sufficient randomness?
What the completed-round check answers
Matching one result does not establish seed-generation quality
Question
What is the game's RTP or value of its paytable?
What the completed-round check answers
Those require the game's model and payout rules; the equality check does not establish them
Question
Were winnings credited or can they be withdrawn?
What the completed-round check answers
A generated result does not establish settlement, account handling or payment trust
Question
Can I access that game from my country?
What the completed-round check answers
A technical proof supplies no country availability
Question
Can I calculate the next winning result?
What the completed-round check answers
The revealed seed belongs to the replaced pair; this workflow does not expose the next active secret

Changing a Client Seed gives you a different input to the calculation. The old seed's revelation lets you inspect completed results. Neither action supplies a profitable choice of seed or a prediction for the next real bet. Cryptocurrency funding is also separate: paying with Bitcoin does not establish that a game exposes its old inputs or a reproducible algorithm.

If your next question is how a generator and its outcome model are tested, use the RNG verification explanation. If you want to interpret the Dice roll's win condition and payout, continue to the dice-games guide.

Lewis Crane

Lewis Crane

Games and slots writer

Games and slots writer covering mechanics, providers, RTP and volatility.

Last updated - By Lewis Crane