Skip to main content

Dice PF

Written by Birate

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 (24081264604508772)

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

Did this answer your question?