When an outcome is generated on a server you don't control, "trust me, it's random" is not an engineering answer. Commit-reveal schemes let a client verify after the fact that the result wasn't rigged, and the pattern generalizes far beyond games — any time a server picks a value the user cares about.
The commit-reveal handshake
Before the round, the server commits to a secret seed by publishing its hash. The client contributes its own seed. The outcome is derived from both:
import { createHash, createHmac } from "crypto";
const serverSeed = randomBytes(32).toString("hex");
const commit = createHash("sha256").update(serverSeed).digest("hex"); // sent first
function outcome(serverSeed, clientSeed, nonce) {
const h = createHmac("sha512", serverSeed)
.update(`${clientSeed}:${nonce}`)
.digest("hex");
return parseInt(h.slice(0, 8), 16) / 0xffffffff; // uniform in [0,1)
}
Why the client seed matters
Without a client contribution, a malicious server could grind seeds until it finds one that produces a favorable result, then publish that hash. Mixing in a value the server couldn't predict when it committed removes that degree of freedom. This is the same reason nonces exist in signed requests.
Verification is the whole point
After the reveal, the client re-hashes the revealed serverSeed, checks it matches the earlier commit, and recomputes the outcome itself. If either check fails, the server cheated. Ship a small open verifier so users can run it independently — a scheme nobody can audit is theater.
Reference
Operators that publish their fairness scheme make good study material because the verifier is exposed to the public. Looking at how a site like play at Wyns Casino documents its seed commitment and lets players re-derive a result is a compact example of turning "trust us" into "check it yourself."
Takeaway
Commit to a hashed seed, mix in a client seed the server can't predict, derive the outcome via HMAC, and hand users a verifier. The cryptography is three functions; the trust model is the actual deliverable.
Top comments (0)