← Back to lotto

Provably-fair proof

This page reproduces the winner computation from public inputs. You can recompute every step in your browser's DevTools — don't trust our math, verify it.

1. Pre-commit (server_seed_hash)

Published when the lotto went live (2026-04-15T04:23:02.640Z).

d95b17f1833302d4eca9e0415757f2a7f99de64a722dce50fb5836f971da63a4

2. Reveal (server_seed)

Revealed after draw (2026-04-16T00:43:28.791Z).

254279f7f6df205f33e670056fbbed52e9a6ea3219731379411bb3d05e2ebc6f

Hash check: ✓ sha256(server_seed) === published hash

3. Client seed inputs (all sold tickets)

#WalletWinner?
1did:pr...1fei
2did:pr...1fei
3did:pr...1fei
4did:pr...1fei
5did:pr...1fei
6did:pr...1fei
7did:pr...1fei
8did:pr...1fei
9did:pr...1fei
10did:pr...1fei
11did:pr...1fei
12did:pr...1fei
13did:pr...1fei
14did:pr...1fei
15did:pr...1fei
16did:pr...1fei
17did:pr...1fei
18did:pr...1fei
19did:pr...1fei
20did:pr...1fei
21did:pr...1fei
22did:pr...1fei
23did:pr...1fei
24did:pr...1fei
25did:pr...1fei
26did:pr...1fei
27did:pr...1fei
28did:pr...1fei
29did:pr...1fei
30did:pr...1fei
31did:pr...1fei
32did:pr...1fei
33did:pr...1fei
34did:pr...1fei
35did:pr...1fei
36did:pr...1fei
37did:pr...1fei
38did:pr...1fei
39did:pr...1fei🎉
40did:pr...1fei
41did:pr...1fei
42did:pr...1fei
43did:pr...1fei
44did:pr...1fei
45did:pr...1fei
46did:pr...1fei
47did:pr...1fei
48did:pr...1fei
49did:pr...1fei
50did:pr...1fei

4. Derived client_seed

client_seed = sha256(sorted by entry_number, joined as "N:wallet" with '|')

9e808f419deebc7b13e6e0047c7e39708094cd18b13c50599c4b799abba9ce72

5. Winner computation

HMAC-SHA256(server_seed, "client_seed:lotto_id"), first 16 hex chars, mod sold_count (50).

hmac = 836a84f0f6f4451e35f5deb5114b67832e2f7e0acf2ef611da8b7ff8313e9ae9

Computed index: 38 → winning entry: #39

6. Independent verification

Show JS snippet (paste into DevTools)
const seed = "254279f7f6df205f33e670056fbbed52e9a6ea3219731379411bb3d05e2ebc6f";
const hashStr = "d95b17f1833302d4eca9e0415757f2a7f99de64a722dce50fb5836f971da63a4";
const clientSeed = "9e808f419deebc7b13e6e0047c7e39708094cd18b13c50599c4b799abba9ce72";
const lottoId = "76024d01-b272-4ec9-a84f-ab3252955765";
const sold = 50;
const entropy = null;

async function run() {
  const enc = new TextEncoder();
  const seedBytes = enc.encode(seed);
  const hashed = await crypto.subtle.digest("SHA-256", seedBytes);
  const recomputed = [...new Uint8Array(hashed)]
    .map((b) => b.toString(16).padStart(2, "0")).join("");
  console.log("hashOk:", recomputed === hashStr);

  const key = await crypto.subtle.importKey(
    "raw", seedBytes, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]
  );
  const message = entropy
    ? clientSeed + ":" + lottoId + ":" + entropy
    : clientSeed + ":" + lottoId;
  const sig = await crypto.subtle.sign("HMAC", key, enc.encode(message));
  const hex = [...new Uint8Array(sig)]
    .map((b) => b.toString(16).padStart(2, "0")).join("");
  const idx = Number(BigInt("0x" + hex.slice(0, 16)) % BigInt(sold));
  console.log("hmac:", hex);
  console.log("winnerIndex:", idx);
}
run();