-
Notifications
You must be signed in to change notification settings - Fork 0
Algorithm
Lucky Spin's outcome is fully deterministic: the same
(serverSeed, clientSeed, nonce, weights) always produces the same segment. Here is exactly what the
server computes — the verifier in this repo reproduces it byte-for-byte.
Before your first spin, the site shows:
commitment = SHA-256(serverSeed) // 64 hex chars, lowercase
The raw serverSeed stays secret while it is active. The commitment proves the seed already existed
and cannot be swapped later — any change would produce a different SHA-256.
For each spin:
digest = HMAC-SHA256(key = serverSeed, message = "clientSeed:nonce:cursor") // cursor starts at 0
-
serverSeedis the HMAC key (UTF-8 bytes). -
messageis the UTF-8 stringclientSeed+:+nonce+:+cursor. - The result is 32 bytes.
The 32-byte digest is read as four 8-byte big-endian unsigned integers (uint64). To keep the odds
exactly as configured we reject the small biased tail:
total = sum(weights)
limit = 2^64 - (2^64 mod total) // largest exact multiple of total
For each 8-byte word in order: if word >= limit, skip it (biased — would distort odds); otherwise it
is accepted. If all four words are skipped, increment cursor and re-HMAC (astronomically rare).
The accepted word is reduced and walked across the cumulative weights:
pick = acceptedWord mod total
acc = 0
for i in 0..weights.length-1:
acc += weights[i]
if pick < acc: return i // this is the winning segment index
segmentIndex indexes into the wheel's segment list (weight > 0 only, in prize-table order). The prize
shown is segments[segmentIndex].
When you Rotate the seed, the site permanently retires it and reveals the original serverSeed.
You can then check SHA-256(serverSeed) == commitment and re-run every past spin under that seed.
-
verify.js— Node.js (usescrypto), CLI +--selftest -
index.html— offline browser (Web Cryptosubtle.digest/subtle.sign) -
test-vectors.json— known-answer cases both must reproduce
Both use BigInt for exact uint64 arithmetic. See the server's ProvablyFairWheel for the canonical
source.