Memoraloo

Don't trust us. Verify us.

Verify this draw.

Lionel Messi Official FIFA World Cup Back Signed & Framed Argentina 2026 Home Shirt — Match IssueCommitment publishedStatus seed sealed until drawBack to competition ↗
  1. The commitment

    Published before any entry was sold

    We generated a secret server seed and published its SHA-256 hash the moment this competition opened. Changing the seed afterwards would break the hash — publicly and permanently.

    SHA-256 commitment
    73efb819b64600e55d03cc0c6c41778bd8f986ec831acd5d173d40d874e538ae
  2. The public entrant list & client seed

    Snapshotted and published at the draw

    Ticket numbers are allocated at random within the fixed pool of 20,000 — which numbers you hold never changes your odds (tickets held ÷ tickets sold). The draw selects a position among valid sold tickets, so an unsold number can never win. The full ticket list is public: ticket numbers (JSON) — live until the draw snapshots it (refunded entries drop out, per the terms).

    The client seed is the SHA-256 of slug:entryCount:listHash:closesAt where listHash is the SHA-256 of that exact ticket list — the outcome is bound to the published entrant set, and the seed behind it was committed before a single ticket was sold.

  3. The result

    Awaiting draw

    This competition has not been drawn yet. The server seed stays sealed until the draw — it will be revealed here, next to the commitment above, so the two can be checked against each other.

  4. Recompute it yourself

    Any machine, ~5 lines

    Run this in Node.js with the revealed values — it must print the published hash and the same winning entry:

    const { createHash, createHmac } = require("crypto");
    const sha256 = (s) => createHash("sha256").update(s).digest("hex");
    
    // numbers = the published list at /api/verify/<slug>/numbers
    const sorted = [...numbers].sort((a, b) => a - b);
    const entryCount = sorted.length;
    
    // 1. Check the commitment and the ticket-list hash
    console.log(sha256(serverSeed));          // must equal the published hash
    const listHash = sha256(sorted.join(",")); // must equal the published one
    const clientSeed = sha256(`${slug}:${entryCount}:${listHash}:${closesAt}`);
    
    // 2. Recompute the winning position
    const key = ["DRAW", slug, serverSeed, clientSeed, entryCount].join("-");
    const hmac = createHmac("sha256", key).digest("hex");
    const value = parseInt(hmac.slice(0, 13), 16);
    const position = Math.floor((value / 2 ** 52) * entryCount) + 1;
    
    // 3. The winner is the position-th ticket, ascending
    console.log("Winning ticket:", sorted[position - 1]);