Logo

Transparency

How Our Competitions Work — and How You Can Verify Them

Every competition on this platform is backed by certified quantum hardware randomness and a published cryptographic record. This page explains what that means, how winners are selected, and how you can independently confirm — using your own computer — that any competition result is genuine.

You don't have to take our word for it. The maths is open, the tools are free, and the verification requires no special skills beyond running a command in a terminal.


The Short Version

  • The winning selections are determined entirely by a 32-byte seed generated by a certified quantum random number generator at the moment of the draw.
  • Before a single winner is picked, a cryptographic hash of that seed (the commitment) is locked in. We cannot change the seed or the outcome after the fact without the commitment hash changing.
  • Every step of the selection process is recorded in a tamper-evident transcript, which is also hashed.
  • All three values — the commitment hash, the seed, and the transcript hash — are printed on the draw certificate and can be fed into an open-source verifier to confirm the result independently.

  • The Randomness Source

    Randomness in computing is surprisingly hard to do well. Software algorithms can appear random but are ultimately deterministic —given the same starting state, they produce the same sequence. That's not good enough for a fair draw.

    Our platform uses a dedicated ID Quantique Quantis PCIehardware quantum random number generator. This device produces genuine randomness from quantum optical processes: it measures the behaviour of individual photons, which is fundamentally unpredictable by the laws of physics — not just "hard to predict", but provably without a hidden pattern. No algorithm, no seed, no back-door.

    The device's serial number is printed on every draw certificate. This lets you confirm which physical hardware unit was used for each draw.

    How Winners Are Selected

    Step 1 — Entropy is reserved

    At the instant a draw is triggered, exactly 32 bytes of raw quantum entropy are drawn from the hardware pool. This value becomes the reveal seed. It is consumed immediately and cannot be reused.

    Step 2 — A commitment is made

    Before the first winner is chosen, the system computes: commitment_hash = SHA-256( draw_id (the unique identifier for this draw) ‖ total_entries (4 bytes, big-endian) ‖ number_of_winners (4 bytes, big-endian) ‖ number_of_alternates (4 bytes, big-endian) ‖ reveal_seed (32 bytes) )

    This hash is published as part of the result. Because SHA-256 is a one-way function, the only way to produce the same hash is to have the exact same inputs. The commitment proves the seed was fixed before selection began — it is mathematically impossible to swap the seed for a different one without the hash changing.

    Step 3 — Winners are drawn

    A deterministic random number generator is seeded with the reveal seed and used to select the winning entries one by one. The algorithm is described in full in the Technical Detailssection below. Every random number generated — including any that are discarded for statistical reasons — is written to a transcript as it is produced.

    Step 3b — Alternates are drawn (if requested)

    If the draw includes alternates, they are drawn immediately after the winners using the same RNG stream. Alternates are drawn from the remaining pool — no entry can be both a winner and an alternate. Every alternate draw is recorded in the same transcript.

    Step 4 — The transcript is sealed

    Once all winners and alternates are selected: transcript_hash = SHA-256(transcript) The transcript records every operation in the draw in order. If even one winner or alternate were swapped out, or the draw replayed with different parameters, the transcript hash would be completely different.

    Step 5 — The certificate is issued

    The draw certificate contains the commitment hash, the reveal seed, the transcript hash, the list of winners, and (if applicable) the list of alternates. Anyone can feed these values into the open-source verifier tools to replay the draw independently and confirm the result.

    Reading the Draw Certificate

    The PDF certificate issued after each draw contains the following fields:

    FieldWhat it means
    Draw IDA unique identifier for this specific draw
    ReferenceA label set by the draw organiser (e.g. competition name)
    Drawn AtThe exact UTC timestamp when the draw was executed
    Total EntriesThe total number of entries in the pool
    Number of WinnersHow many winners were drawn
    Number of AlternatesHow many alternates were drawn (omitted if zero)
    RNG SourceAlways 'Quantis PCIe Hardware QRNG' — the hardware device used
    RNG SerialThe serial number of the specific hardware unit
    Discarded SamplesHow many random values were discarded for bias prevention (see below)
    Commitment HashSHA-256 hash computed from the draw parameters and seed before the draw
    Reveal SeedThe 32-byte quantum entropy seed (shown as 64 hexadecimal characters)
    Transcript HashSHA-256 hash of the complete draw operation log
    WinnersThe selected entry numbers, in draw order
    AlternatesAlternate entry numbers drawn after winners (omitted if none were requested)

    Why are there three hashes?

    Each one provides a different guarantee:
    • Commitment hash — proves the seed was locked in before selection. If you hold this hash from before the draw, you can verify the seed was not chosen after the outcome was known.
    • Reveal seed — the raw quantum entropy. Feeding this into the verifier replays the entire draw from scratch and produces the same winners.
    • Transcript hash — proves every operation happened in the recorded order. Changing any winner, or changing their sequence, breaks this hash.

    Verifying a Draw Yourself

    You can replay any draw on your own computer using one of our open-source verifier tools. They are standalone programs that require no internet connection, no account, and no trust in us — the algorithm is public and the tools can be audited by anyone.

    Download the verifier

    Three implementations are available. All produce identical results.
    LanguageRequirementDownload
    GoGo 1.21+Download verify.go
    PythonPython 3.6+Download verify.py
    JavaScriptNode.js 18+Download verify.js

    Python and JavaScript verifiers use only their standard libraries — no package installation needed.

    Install

    Go

    # Unzip the downloaded archive, then: go build -o qrng-verify ./verify.go # Move to somewhere on your PATH if you like: mv qrng-verify /usr/local/bin/

    Python — no installation required:

    python3 verify.py --help

    JavaScript — run with Node.js:

    node verify.js --help

    Running a Verification

    All values you need are printed on the draw certificate. Copy them exactly as shown — capitalisation does not matter for the hex values.

    Arguments

    --draw-id The Draw ID from the certificate --total-entries Total number of entries --number-of-winners Number of winners drawn --number-of-alternates Number of alternates drawn (default 0) --reveal-seed The Reveal Seed (64 hex characters) --commitment-hash The Commitment Hash to verify against (optional) --transcript-hash The Transcript Hash to verify against (optional) --winners The winners to verify, comma-separated (optional) --alternates The alternates to verify, comma-separated (optional) --one-indexed Include this flag if the certificate shows 1-indexed winners/alternates

    If you omit --commitment-hash , --transcript-hash , or --winners , those checks are skipped and the tool simply prints the computed values.

    Example

    Suppose your certificate shows: Draw ID: summer-prize-draw-2026 Total Entries: 8500 Number of Winners: 5 Reveal Seed: 9f2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2 Commitment Hash: c8d4f3e9a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6 Transcript Hash: d7c6b5a49382f1e0c9d8b7a6f5e4d3c2b1a0f9e8d7c6b5a4938271f0e9d8c7b6 Winners (0-indexed): 7823, 412, 5901, 3367, 88

    Python:

    python3 verify.py \ --draw-id "summer-prize-draw-2026" \ --total-entries 8500 \ --number-of-winners 5 \ --reveal-seed "9f2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2" \ --commitment-hash "c8d4f3e9a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6" \ --transcript-hash "d7c6b5a49382f1e0c9d8b7a6f5e4d3c2b1a0f9e8d7c6b5a4938271f0e9d8c7b6" \ --winners "7823,412,5901,3367,88"`}

    JavaScript:

    {`node verify.js \ --draw-id "summer-prize-draw-2026" \ --total-entries 8500 \ --number-of-winners 5 \ --reveal-seed "9f2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2" \ --commitment-hash "c8d4f3e9a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6" \ --transcript-hash "d7c6b5a49382f1e0c9d8b7a6f5e4d3c2b1a0f9e8d7c6b5a4938271f0e9d8c7b6" \ --winners "7823,412,5901,3367,88"

    Go:

    qrng-verify \ --draw-id "summer-prize-draw-2026" \ --total-entries 8500 \ --number-of-winners 5 \ --reveal-seed "9f2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2" \ --commitment-hash "c8d4f3e9a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6" \ --transcript-hash "d7c6b5a49382f1e0c9d8b7a6f5e4d3c2b1a0f9e8d7c6b5a4938271f0e9d8c7b6" \ --winners "7823,412,5901,3367,88"

    Expected output:

    === Draw Verification ===
    Draw ID:           summer-prize-draw-2026
    Total Entries:     8500
    Number of Winners: 5
    Reveal Seed:       9f2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2
    Commitment Hash:   c8d4f3e9a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6
    Transcript Hash:   d7c6b5a49382f1e0c9d8b7a6f5e4d3c2b1a0f9e8d7c6b5a4938271f0e9d8c7b6
    Discarded Samples: 0
    Winners (0-idx):   7823,412,5901,3367,88
    
    ✓ commitment_hash  MATCH
    ✓ transcript_hash  MATCH
    ✓ winners          MATCH
    
    Verification PASSED.

    Example — with alternates

    When a draw includes alternates, the certificate will show additional fields. Pass --number-of-alternates and --alternates alongside the standard arguments. Suppose your certificate shows: Draw ID: summer-prize-draw-2026 Total Entries: 8500 Number of Winners: 5 Number of Alternates: 3 Reveal Seed: 9f2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2 Commitment Hash: a1e4f7b2c5d8e3f096a2b1c4d7e0f3a6b9c2d5e8f1a4b7c0d3e6f9a2b5c8d1e4 Transcript Hash: f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2 Winners (0-indexed): 7823, 412, 5901, 3367, 88 Alternates (0-indexed): 2204, 6711, 1055

    Python:

    python3 verify.py \ --draw-id "summer-prize-draw-2026" \ --total-entries 8500 \ --number-of-winners 5 \ --number-of-alternates 3 \ --reveal-seed "9f2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2" \ --commitment-hash "a1e4f7b2c5d8e3f096a2b1c4d7e0f3a6b9c2d5e8f1a4b7c0d3e6f9a2b5c8d1e4" \ --transcript-hash "f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2" \ --winners "7823,412,5901,3367,88" \ --alternates "2204,6711,1055"

    JavaScript:

    node verify.js \ --draw-id "summer-prize-draw-2026" \ --total-entries 8500 \ --number-of-winners 5 \ --number-of-alternates 3 \ --reveal-seed "9f2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2" \ --commitment-hash "a1e4f7b2c5d8e3f096a2b1c4d7e0f3a6b9c2d5e8f1a4b7c0d3e6f9a2b5c8d1e4" \ --transcript-hash "f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2" \ --winners "7823,412,5901,3367,88" \ --alternates "2204,6711,1055"

    Go:

    qrng-verify \ --draw-id "summer-prize-draw-2026" \ --total-entries 8500 \ --number-of-winners 5 \ --number-of-alternates 3 \ --reveal-seed "9f2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2" \ --commitment-hash "a1e4f7b2c5d8e3f096a2b1c4d7e0f3a6b9c2d5e8f1a4b7c0d3e6f9a2b5c8d1e4" \ --transcript-hash "f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2" \ --winners "7823,412,5901,3367,88" \ --alternates "2204,6711,1055"

    Expected output:

    === Draw Verification ===
    Draw ID:              summer-prize-draw-2026
    Total Entries:        8500
    Number of Winners:    5
    Number of Alternates: 3
    Reveal Seed:          9f2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2
    Commitment Hash:      a1e4f7b2c5d8e3f096a2b1c4d7e0f3a6b9c2d5e8f1a4b7c0d3e6f9a2b5c8d1e4
    Transcript Hash:      f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2
    Discarded Samples:    0
    Winners (0-idx):      7823,412,5901,3367,88
    Alternates (0-idx):   2204,6711,1055
    
    ✓ commitment_hash  MATCH
    ✓ transcript_hash  MATCH
    ✓ winners          MATCH
    ✓ alternates       MATCH
    
    Verification PASSED.

    If your certificate shows 1-indexed winners and alternates

    Some draws display entries numbered from 1 (where 1 = the first entry in the pool). If the certificate says "1-indexed", add --one-indexed and pass both winners and alternates exactly as printed on the certificate — the flag applies to both lists:

    python3 verify.py \ --draw-id "summer-prize-draw-2026" \ --total-entries 8500 \ --number-of-winners 5 \ --number-of-alternates 3 \ --reveal-seed "9f2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2" \ --winners "7824,413,5902,3368,89" \ --alternates "2205,6712,1056" \ --one-indexed

    Exit codes

    CodeMeaning
    0Verification passed
    1A hash, winner, or alternate did not match — the result should be queried
    2A required argument was missing or invalid

    What the Verification Proves

    Running the verifier and seeing Verification PASSED confirms three things:

    1. The seed was fixed before the draw. The commitment hash matches, which means the 32-byte quantum seed was locked in — along with the draw parameters — before any winner was selected. No one could have seen the outcome and then chosen a different seed.
    2. The exact draw algorithm was followed. The transcript hash matches, which means the recorded sequence of operations produced these exact winners and alternates. Swapping any winner or alternate, or reordering them, produces a different transcript hash.
    3. The winners and alternates came from genuine randomness. The seed is 32 bytes of certified hardware quantum entropy. The verifier replays the selection from that seed and arrives at the same winners and alternates — meaning no alternative list is consistent with this seed.

    Technical Details

    This section is for those who want to understand or independently implement the algorithm. The verifier source code is the authoritative reference.

    Seeded RNG

    The quantum seed is used to drive a counter-mode SHA-256 random number generator: seed = reveal_seed (32 bytes) counter = 0 Uint32(): input = seed ‖ decimal_string(counter) e.g. counter=42 → "42" in ASCII output = SHA-256(input) result = first 4 bytes of output, interpreted as a big-endian unsigned integer counter += 1 return result The counter is formatted as a plain decimal ASCII string (not as raw bytes). This ensures consistent behaviour across Go, Python, and JavaScript.

    Eliminating modulo bias

    Selecting a random integer in [0, max) by computing r % max on a uniformly distributed 32-bit value introduces a small bias unless max divides 2^32 exactly. Our implementation removes this bias with rejection sampling:

    limit = floor(2^32 / max) × max loop: r = Uint32() if r < limit: return r % max ← accepted (perfectly uniform) discard r ← rejected (would cause bias)

    Only values below limit are accepted, so every outcome in [0, max) has exactly the same probability. The number of discarded values is reported on the certificate as Discarded Samples and is usually zero. For draws with up to 100 million entries, the expected discard rate is under 0.01%.

    Selection without replacement

    A running set of already-selected indices ensures each entry can win at most once. If the RNG draws an index that has already been selected, that draw is silently skipped and the loop continues. Every call to the RNG — including skipped collisions — is recorded in the transcript.

    Commitment construction

    commitment_input = UTF-8 bytes of draw_id ‖ total_entries as a 4-byte big-endian unsigned integer ‖ number_of_winners as a 4-byte big-endian unsigned integer ‖ number_of_alternates as a 4-byte big-endian unsigned integer ‖ reveal_seed (32 raw bytes) commitment_hash = SHA-256(commitment_input), encoded as lowercase hex

    Transcript format

    The transcript is a binary record of every operation during the draw. Each entry is prefixed with a type byte:
    PrefixPayloadMeaning
    0x104-byte length + UTF-8 bytesDraw ID string (first record)
    0x014-byte big-endian uint32RNG sample, accepted value, or parameter
    0x024-byte big-endian uint32Confirmed winner index
    0x034-byte big-endian uint32Confirmed alternate index
    0xff(none)Rejected sample (bias discard)
    Full sequence: 0x10 ← draw ID 0x01 ← parameter 0x01 ← parameter 0x01 ← parameter # repeated for each winner: 0x01 ← raw RNG output [ 0xff ... ] ← zero or more rejections 0x01 ← rng_sample % total_entries 0x02 ← winner confirmed # (if accepted_value was already in the selected set, only 0x01 records appear; loop continues) # repeated for each alternate (same RNG stream, continues from winners): 0x01 ← raw RNG output [ 0xff ... ] ← zero or more rejections 0x01 ← rng_sample % total_entries 0x03 ← alternate confirmed # (if accepted_value was already in the selected set, only 0x01 records appear; loop continues) transcript_hash = SHA-256(all bytes above concatenated), encoded as lowercase hex
    Home
    Competitions
    Cart
    My Account