How we pick winners

Every giveaway closes at a fixed time. We freeze the list of confirmed entries, generate a random number with the same cryptography browsers use for secure connections, and combine it with the frozen list to pick one entry. The random number, the list (as anonymous hashes), and the result are published for every draw, so anyone can re-run the math and get the same winner. Nobody, including the creator or us, can choose or change the result. If a winner doesn't claim within 72 hours, the next backup from the same draw is used, and that's published too.

The exact steps

  1. At close, every confirmed entry becomes a row: entry id, a hash of the email, and its entry count (1 plus any bonus entries). Rows are sorted by entry id and hashed with SHA-256. That hash is the snapshot hash. Nothing after this point can change the pool.
  2. At draw time we generate 32 random bytes (server random) from the operating system's secure generator. This happens only after the snapshot, never before.
  3. seed = SHA-256(giveaway id + snapshot hash + close timestamp + server random), all as plain text joined with no separators.
  4. Lay every entry out in a line, each repeated by its entry count, in entry-id order. index = seed (as a big integer) mod the length of that line. The entry at that index wins.
  5. Backups: the same with seedk = SHA-256(seed + k) for k = 1, 2, 3, skipping anyone already picked.

Check it yourself

Every draw record page links to the entrant list (hashes only) and the record as JSON. Download both and run verify-draw.js with Node:

node verify-draw.js record.json entrants.csv

To find your own row, compute SHA-256 of your lowercased email followed by the giveaway's salt (shown on the record page).

What we never do