Provably fair giveaways

The winner of every Arc giveaway is locked in before anyone enters - and you can check the math yourself. No trust required, just hashes.

Check a draw

Paste a giveaway id and your browser will recompute every hash and replay every pick locally. We never see what you check.

You can find the id at the bottom of any Arc giveaway embed.

Four steps, zero trust

secret server seedf3a9c04b21…77d0be
SHA-256
public commitmentc41d09aa38…88b2e1

Sealed into the giveaway embed before the first entry - it can never be changed afterwards.

Try it yourself

This runs the exact draw algorithm in your browser with a fresh random seed and eight pretend entrants. No server involved.

What this proves - and what it doesn't

The proof shows that given the entry list, the winner was decided by math alone. The bot couldn't pick a favourite, swap the secret after seeing who entered, or quietly reroll until it liked the result - any of that would break the hashes the verifier checks.

It doesn't say anything about who was allowed to enter. If a server only lets certain people into the giveaway, the draw among those people is still perfectly fair - but fairness of the guest list is up to the humans running it.

The exact formulas

Everything is computed over UTF-8 bytes with lowercase hex output. You can reproduce a draw in any language in a few lines.

commitment  = sha256(server_seed)
client_seed = sha256(giveaway_id + ":" + message_id + ":" + entries.join(","))
digest_n    = hmac_sha256(key = server_seed, msg = client_seed + ":" + nonce)
index_n     = int(digest_n[0:13], 16) % len(pool)
winner_n    = pool.remove(index_n)
  • server_seed is 32 random bytes as 64 hex chars, generated before the giveaway starts and revealed after the draw.
  • entries are the entrants' Discord user ids as decimal strings, comma-joined in entry order. message_id is the giveaway message id as a decimal string ("0" if absent).
  • Nonces count up from 0 across the lifetime of a giveaway: the initial draw uses 0, 1, 2, … and rerolls continue where the last draw stopped.
  • Each pick removes the winner from the pool, so one seed pair can fairly draw any number of distinct winners.
  • The first 13 hex chars are 52 bits - small enough for exact integer math in every language, unbiased for any realistic pool size.