terms used
• client seed: a string chosen by the player (or automatically generated if you don't choose one)
• server seed: 64-character hex string generated using crypto.randomBytes(32)
• nonce: the round number you're on, increases by 1 for every round across all house games
• HMAC: cryptographic function that mixes unhashed server seed, client seed and nonce to produce a result
here's a 3rd party HMAC tool to verify each step for yourself: https://cryptii.com/pipes/hmac - (or any other one you prefer)
how HMAC is used for the final result, example round to demonstrate
unhashed server seed: e8c83961a3961baee67cc08da34ada1c00a4515450a3cdbd2b1db81a35ca7f72
client seed: UzR5CIqog4DXox5H
nonce: 21
here's what the "message" part of the HMAC looks like: <clientSeed:nonce> which gives you UzR5CIqog4DXox5H:21 (the next round after this one would be UzR5CIqog4DXox5H:22)
the ”key” part is your unhashed server seed
if you're using the 3rd party site above to follow along it would look like this:
this results in the following hexadecimal string:
24081264c9bc7eb7b48297773a75dc02f51898e96d902b79ecad2c73bfb2d7c1
the first 4 bytes (8 hex characters) are then taken from this string and converted from hexadecimal → decimal (24081264 → 604508772)
the decimal value is then compared against the fairness range (<4,294,959,453 ) if the number passes, it's used for the roll calculation - if not, the next 4 bytes are tried (this is done to avoid miniscule bias towards lower numbers)
once an acceptable value is found (604,508,772) the calculation looks like this: 604508772 % 10001 = 8328 / 100 = 83.28*
*
*
that means “if you split 604508772 into groups of 10001, 8328 is left over” (divided by 100 to display as decimal)
10001 is the total number of possible dice outcomes (0–10000)
83.28 aligns with what the actual result was, and what is displayed if you verify the round here
yeah but you can just give me a rigged seed how does this prove anything?
server seeds are randomly generated bytes, but even if they weren't - your client seed makes it impossible for us to "rig" the game by cherrypicking seeds. you can try this for yourself in the HMAC tool by changing the "message" part even slightly, this results in a completely different and unpredictable output. every last bit of the dice roll can be verified.
there is no possible way for Duel to fuck with your odds or use a different code for results than displayed on the fairness page.
how this could be cheated and how you'd notice
if your hashed server seed wasn't shown before playing
if your hashed server seed was shown to you only after committing to a client seed
if the algorithm was changed to use a different part of the hash (you can verify that this isn't the case with steps above)
if your hashed server seed didn't match the unhashed seed when checking with a SHA-256 calculator
TL;DR
client seed, nonce and server seed are used for the final result of each dice roll, this can be verified using an online HMAC tool
maximum fair number for final result can't be over 4,294,959,453, meaning each individual number has 429,453 (4,294,959,453 / 10001) possible 32-bit values within the acceptable range
each number has the exact same odds with any client & server seed combination
losing money as a result of gambling doesn't mean the game is rigged