Skip to main content

Crash PF

Written by Birate

terms

server seed: 64-character hex string generated using crypto.randomBytes(32) and hashed with SHA-256

drand seed: essentially your client seed from other modes, ours is from https://www.drand.love/ - it's public, unpredictable and verifiably random information

nonce: always a 0, but means the round number in other modes

drand round ID: points to a future randomness value on the drand's public timeline

HMAC: cryptographic function that mixes unhashed server seed, drand 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 to get the crash point, example round to demonstrate

server seed: 72ebf12bfaf8d996438fcf8a4a88c01dbb022c05f4ac831b392d196a67ff9261

drand:

95812946c71502a50b85c0b6c8ad0bb821de4d5a2c011717ba0a668843295bfecd85aee347544c89cf809bad32a9d3fc

first, the drand randomness is converted into bytes and decoded to UTF-8
invalid sequences are replaced by unicode character " " (U+FFFD)

some byte sequences can't exist in UTF-8, this is standard for text decoder and doesn't affect fairness

use this command in browser console to easily decode the Drand

const d='REPLACEWITHDRAND';console.log(Array.from(new TextEncoder().encode(new TextDecoder().decode(Uint8Array.from(d.match(/.{2}/g).map(x=>parseInt(x,16)))))).map(b=>b.toString(16).padStart(2,'0')).join('')+'3a30');

(the 3a30 added to the end is due to the nonce value, this is 0 for every round which means it doesn't change)

here's what the provided Drand Randomness looks like as hexadecimal bytes: efbfbdefbfbd2946efbfbd1502efbfbd0befbfbdefbfbdefbfbdc8ad0befbfbd21efbfbd4d5a2c011717efbfbd0a66efbfbd43295befbfbdcd85efbfbdefbfbd47544cefbfbdcf80efbfbdefbfbd32efbfbdefbfbdefbfbd3a30

that with the HMAC key (unhashed server seed) gives the following hexadecimal value: 663e918e0174be61054c5a4eaec63328f5fc1d626f5be4a00801271fa8acc04d


how does that equate to a crash number

the first 8 hex characters are used from the final string, in this case "663e918e" then converted from hexadecimal -> decimal (663e918e -> 1715376526)

here's the formula to calculate crash point using the decimal value: (2^32 / (1715376526 + 1)) * (1 - 0.001) = 2.50130059562

the final crash point was at 2.50x as can be verified using the fairness/verify page


but your minions are doing tricks in the backend to make it crash

Drand randomness is public and verifiable, Duel doesn't have control over it. the hashed server seed and drand round ID's are visible before the round starts, this locks in the result - proving it can't be altered or manipulated by anyone

Drand round ID and the corresponding Drand Randomness string can be found here: api.drand.sh/v2/beacons/quicknet/rounds/22842664 with 22842664 being the round above

due to the drand value being public and random, committing to a certain drand round ID and server seed before the drand itself is published means not even god himself could rig the game


TL;DR

• drand acts as the client seed from other modes

• duel's server seed signs it

• combination of drand and server seed decide the multiplier

• everyone can verify every last bit for themselves

if a drand round is committed to & the hashed server seed is shown before the round starts, it's provably fair.

Did this answer your question?