Skip to main content

Verify this draw

Win A Toy Story Interactive Talking Action Figure #5 was drawn on 26 Aug 2026. The winner was Jessica D. from Milton Keynes with ticket #6.

Method

Verified auto-draw

Tickets in the draw

57

Winning ticket

#6

Winner's odds

1 in 11

In plain English

Before entries closed, we locked in a secret number and published a “fingerprint” of it (a one-way SHA-256 code) that proves we couldn’t change it later. After entries closed, that number, mixed with a public source of randomness that nobody controls, picked the winning ticket. So the result couldn’t be set in advance or predicted by anyone. The steps further down let you re-run it and land on the same ticket yourself.

How this draw is provable

Before entries closed we published a commitment: a one-way fingerprint (SHA-256) of a secret random seed. After the draw we revealed the seed. Because the commitment was public before entries closed, the seed could not have been changed afterwards to draw a particular ticket.

The draw also folds in a public randomness beacon (drand, the League of Entropy) whose value is only published after entries close. Anyone can re-fetch the exact beacon round below and confirm the same value went into the draw.

Commitment (published before entries closed)
d09ea7d7293e24d0805d5b9ff21c4944428a7ded61fb842c32233e99ddce0b7f
Revealed seed (published after the draw)
19f275003964f4e2d0b0df52172a98c7c0f4d3d3c0c0570453ce91ecdd7dc82a
Beacon round (emitted after close) & its public value
Round 6,411,387 on the drand chain 8990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce
ba5b42d12e9b19135fb9db9175f4991ee47c88cc14c9e24f39562999a3d9b1d4
Re-fetch it: curl https://api.drand.sh/8990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce/public/6411387

Check it yourself

1. The seed matches the commitment

Run SHA-256 on the revealed seed - it equals the commitment above. For example, in a terminal:

printf '%s' '19f275003964f4e2d0b0df52172a98c7c0f4d3d3c0c0570453ce91ecdd7dc82a' | sha256sum

2. The seed and the beacon draw the winning ticket number

The 57 ticket numbers that went into this draw are lined up in ascending order; the locked-in seed mixed with the post-close beacon value shown above (both are in the $msg below) picks one. The seed was committed before entries closed, and the public beacon that decides the winner didn't exist until after - so the result couldn't be set in advance or predicted. Sort the numbers in play (their fingerprint is below, and the full set is in the entrants list) and recompute - you'll get ticket #6:

$seed    = '19f275003964f4e2d0b0df52172a98c7c0f4d3d3c0c0570453ce91ecdd7dc82a';
$tickets = [ /* the 57 ticket numbers in the draw, sorted ascending */ ];
$total   = count($tickets);
$msg     = 'draw:01a02b7d-d587-701c-a65b-066bacba5075:'.$total.':ba5b42d12e9b19135fb9db9175f4991ee47c88cc14c9e24f39562999a3d9b1d4';   // note: the trailing value is the drand beacon above
$span    = 1 << 60;                        // 60-bit space
$limit   = intdiv($span, $total) * $total; // reject above this to remove bias
$i = 0;
do {
    $n = (int) hexdec(substr(hash_hmac('sha256', $msg.':'.$i, $seed), 0, 15));
    $i++;
} while ($n >= $limit);
echo $tickets[$n % $total];                 // => winning ticket #6

3. Ticket #6 belongs to the winner

That ticket number is held by exactly one entry - Jessica D. from Milton Keynes. We publish a fingerprint of every ticket number in the draw, so the set of numbers can't be altered after the fact, and we hold the full list in our tamper-evident audit trail, available to the Advertising Standards Authority on request.

Ticket-numbers fingerprint
91df067c45acf2435829d72ca5cd541a414dbc5afad7af21f582946e951beb28

How ticket numbers are assigned

On this competition you don’t choose your ticket number, and it isn’t simply the next number in order. When you buy, the system gives you a number using a secret shuffle that was set when the competition opened, before anyone had bought a ticket, and can’t be changed after.

Because that shuffle is secret and gives everyone a different number:

  • Two people can never end up with the same number.
  • Nobody, not you and not us, can guess which number a purchase will get. On this draw the number itself isn’t what picks the winner - that’s the draw above, which nobody can predict.
  • Your number is fixed the instant you buy, and recorded straight away.

We keep the shuffle secret so no one can work out in advance which number a purchase will get, which is what stops anyone targeting a winning ticket. Every number that’s given out still appears in the competition’s entrants list, so the numbers in play are public and can’t be quietly changed later.

You can see them: every entry and its ticket number is listed on the competition’s entrants page.

Prove the shuffle yourself

When the competition opened we published a fingerprint of the secret shuffle key, so it’s on record as fixed before anyone bought:

Shuffle-key fingerprint (published at open)
b1d3319c71190a239ebcc7ffd7f52045454aa7183e29b0e2056c252270394af1
The shuffle key itself (revealed now the competition has ended)
YPW7gbt4WDWLCZGXFQotIHgZSJHkYhmkEFAIMLwI

First check the key matches the fingerprint published at open, then re-run the shuffle for yourself: feed each position 1, 2, 3… through it and you get the 61 ticket numbers in the pool, each exactly once. If it matches the fingerprint and produces a complete set with no repeats, the numbers were genuine and untouched.

Show the method
// 1. the key matches the fingerprint published at open:
printf '%s' 'YPW7gbt4WDWLCZGXFQotIHgZSJHkYhmkEFAIMLwI' | sha256sum        // => b1d3319c71190a239ebcc7ffd7f52045454aa7183e29b0e2056c252270394af1

// 2. re-run the shuffle: position -> ticket number
$seed   = 'YPW7gbt4WDWLCZGXFQotIHgZSJHkYhmkEFAIMLwI';
$domain = 61;   // the pool the numbers are shuffled within
$prf = fn($v,$r) => (int) hexdec(substr(hash('sha256', "$seed:$r:$v"), 0, 8));
$permute = function(int $pos) use ($domain, $prf) {
    $half = (int) ceil(((int) ceil(log($domain, 2))) / 2);
    $mask = (1 << $half) - 1;
    $x = $pos - 1;
    do {
        $l = ($x >> $half) & $mask; $r = $x & $mask;
        for ($i = 0; $i < 4; $i++) { $n = $l ^ ($prf($r, $i) & $mask); $l = $r; $r = $n; }
        $x = ($l << $half) | $r;
    } while ($x >= $domain);
    return $x + 1;
};
// $permute(1), $permute(2), ... are the ticket numbers, in the order they were issued.

See how all our draws work on our fairness & security page, or back to all winners.

?