How it works · what we will not claim

Is a Secret Santa generator safe? Here is exactly what this one does

Every gift-draw site says your draw is private. The sentence costs nothing to write, so it tells you nothing. This page separates the parts of our promise that are properties of how the tool is built from the parts that are only decisions we made, names everyone who could learn something, and hands you a decoder that opens a real sealed link in front of you.

The short version: the draw runs in your browser, there is no server of ours, and the organizer can still open a link they hold if they decide to.

Link length Payload Padded plaintext Requests since load

A real sealed link, made in your browser a moment ago, by the same two files the generator uses — loaded by this page, not copied into it, so this is the live wire format rather than a drawing of it. The people are invented.

The box below opens any sealed link the same way. Paste one meant for somebody else and this screen shows you their assignment, which no page can undo for you. Paste your own.

What we claim

Four claims, kept apart because they are not equally strong.

The whole draw runs in your browser. Nothing you type is transmitted by this site, and the tool works with your wifi switched off. There is no account, no database, and no server of ours to store anything on. Two things are kept on your device, and no more: the site's own code, cached so the tool works offline, and — while a draw tab is open — your own sealed links and the names they are for, so a reload does not destroy a half-distributed draw. That second one holds no pairings, is cleared by the Forget this draw button, and is set out in full in the privacy policy. It is a deliberate exception to the zero-storage default rather than something to leave sitting under a slogan.

Each assignment exists only inside its own link, in the part of a URL after the #. Browsers do not put that part in the request they send to a web server, so it is not in our logs, not in our host's logs, and not in a chat app's link-preview fetch.

The draw is uniformly random over every assignment your rules allow, and the algorithm and the test that checks its distribution are both published.

In a Locked draw, each assignment is sealed to a key the recipient's own device made and sent to nobody. That is the one claim here that is a statement about mathematics rather than about our own interface, and it carries a named exception below.

Who can learn what

Read the last column first. Architecture means the information is not there to be had: no request carries it and no store holds it. Our choice means it exists somewhere and we have decided not to surface it — a promise, and worth weighing as one. Nothing means nothing stops it, which belongs in the same table as the good news.

WhoIn a Quick drawIn a Locked drawWhat stops it
This site Nothing. No name, rule or pairing ever enters a request. Nothing, for the same reason. Architecture
Our host and CDN That some browser fetched some pages, with an IP address and a time. Never a name, never the part after the hash. The same. Architecture
Your chat app The whole message, key included: Slack or Gmail holds something that opens that assignment. The sealed message only. The key that opens it never left the recipient's device. Quick: nothing
Locked: architecture
The organizer Any assignment they open, one link at a time, past a screen naming whose it is. Nothing here shows them the draw. Nothing from the envelopes. But the draw runs in their browser, so devtools open at that moment read the pairing. Quick: our choice
Locked: architecture, one exception
Another participant Their own assignment, plus anyone else's whose link they are handed. Their own only. Quick: nothing stops it
Locked: architecture
Someone who finds a link That one assignment, from a forward, a screenshot or a shared screen. Nothing without that person's keep link. Quick: nothing
Locked: architecture

Two rows carry the design argument. Every server-backed tool removes the organizer's access by adding a company with total access, which turns the first row into a promise instead of a property. We removed the company; the cost lands in the organizer's row, where you can price it.

Where those claims stop

The organizer is holding every envelope. In a Quick draw the key that opens a link travels inside it, so the person handing them out can open one. Our part is real: this tool has no screen, button, or export that shows the organizer who drew whom, and no database that could. That is a property of what we built, not a claim about what a determined person can do with links they hold. Opening someone else's takes a deliberate act, past an interstitial carrying that person's name. A sealed envelope, not a vault: it stops accidents and a glance, not the person carrying it.

A Locked draw has exactly one moment we cannot protect. The envelopes are opaque to whoever hands them out, but the draw itself runs in the organizer's browser, so an organizer watching with developer tools open at that instant sees the pairing. We cannot remove that moment without a server, and a server is what every other tool has. If you would rather nobody had it, hand the draw to someone who is not playing; the organizer-blind guide runs its four tests on this site first.

The carrier keeps the message. No server of ours holds a link, but the moment you send one, Slack, Gmail or WhatsApp stores it, and it will still be in that thread in February. Deleting it is their job, and it is the clause our own first draft of this page got wrong.

A Quick link can be forged. The key ships with the ciphertext, so anyone can mint a link that decrypts perfectly, including one carrying your draw ID. The encryption buys integrity against corruption — a mangled link fails loudly rather than decrypting to a plausible wrong name — and nothing against a fake. The draw ID is the same story: it says two links came from one run, and proves nothing about fairness, validity, or whether anyone looked. It is good for one sentence, which the drop-outs guide uses: any link showing the old ID is dead.

Your browser is not ours to promise about. Chrome's Enhanced Spell Check (behaviour as of August 2026) can ship the contents of a text box to Google for checking — browser level, underneath our page, invisible both to our Content-Security-Policy and to our own meter, which is why the names box on the generator turns spell-checking off. An extension can read any page you have open, this one included.

Small groups leak by arithmetic. Three people have only two possible draws, so anyone who opens their own link knows the rest. The generator prints the size of the draw space and turns it amber below five people. On tightly constrained lists it falls back to a second method whose output obeys every rule but which we do not claim is uniform, and the readout says which you got.

Three ways to check this, strongest first

1. Turn your wifi off. The strongest test, because it runs outside our code and no version of this page can pass it dishonestly. Load the generator with a connection, switch on airplane mode, then type names, set rules and seal the whole draw. If it completes, the work happened on your device: with no network there is no server. One caveat — the reveal page works offline only on a return visit, because a participant arriving for the first time is a cold load.

2. The devtools Network tab. Also outside our code, and it watches continuously. Press F12, or Command-Option-I on a Mac, switch to Network, set the filter to All so websocket traffic is not hidden, and reload. This page's own files arrive; after that, typing a roster and sealing a draw should add nothing. An upload is unmistakable: a POST or PUT, a size that tracks your input, and a server for a destination.

3. The meter on this page. The weakest of the three, and we would rather rank it honestly than lead with it: a counter we wrote, in a page we serve, reporting on requests we made. On the reveal page it is weaker still — the sealed payload was in the address at navigation, before any JavaScript existed, so no arming point can pre-date it. The argument that carries weight there is structural. The fragment, everything after the #, is excluded from the request-target by RFC 3986 section 3.5 and is not carried in a Referer header, so it never reaches a web server. That is not a promise about our conduct; it is what browsers do.

The draw itself

What the draw is. A draw here is a uniform random derangement: a pairing in which everyone gives exactly one gift, receives exactly one gift, and nobody draws themselves. There are 9 such pairings for four people, 44 for five, and 1,334,961 for ten — and this tool is equally likely to produce any of them. That last clause is the part most tools skip. The familiar party shortcut — shuffle everyone into a circle and have each person give to the next — produces only pairings that form a single loop, which is Sattolo's algorithm under a friendlier name. Every result it gives is valid, but it can never produce the three four-person draws where two pairs simply swap, and at twenty people it can reach only about one possible draw in seven. We do not use it, and we do not use the other common shortcut either: shuffling and then swapping the self-draws away is not uniform, however reasonable it looks.

How it is done. The method is rejection sampling, published here because it is the only one whose distribution can be stated in a single line. The tool shuffles the list with a Fisher–Yates shuffle driven by your browser's cryptographic random number generator, checks whether the result breaks any rule — self-draws, household exclusions, last year's pairs — and if it does, throws the whole shuffle away and starts again. Conditioning a uniform distribution on a rule leaves it uniform over whatever survives, so the draw you keep is exactly uniform over the draws your rules allow. The waste is small: with no exclusions beyond self-draws, the expected number of shuffles is 2 for two people, 3 for three, and stays between 2.6 and 2.8 — converging on e ≈ 2.72 — for every group larger than that, at any size. Fewer than one draw in a thousand needs more than sixteen shuffles. Exclusions cost more, roughly a factor of e for each person everyone is excluded from: a group of ten made of five couples takes about eight shuffles. The random numbers themselves come from crypto.getRandomValues through a rejection step of its own, so that no name is fractionally likelier than another — the modulo shortcut that quietly favours the low numbers is not used here. There is no seed. A printed seed would make the draw reproducible by anyone who had it, which on this tool would be a defect rather than a feature.

Where it stops. Three limits, all stated because the tool reports them rather than hiding them. First, exclusions can make a draw impossible, and when they do the tool says which rule is the problem before you press anything: a household can never be larger than half the group, because every one of its members has to give to someone outside it. That is Hall's marriage theorem applied to a party — and where the cause is less obvious, the tool finds the smallest set of people whose combined rules leave them too few recipients, and names them and the rules involved. Second, on very tightly constrained lists rejection sampling would run impractically long — two households of ten inside a group of twenty would need roughly 185,000 shuffles — so after 20,000 attempts the tool switches methods: it builds one valid pairing by direct matching, then randomises it with swaps that are accepted only when the result is still valid. That output obeys every rule, but we cannot prove it gives every valid draw an even chance, so we do not claim it does. The readout says uniform or constrained for the draw you actually got, and this paragraph is the only place either word means anything. Third, uniform across whole draws is not the same as every person being equally likely to draw every other person. Lopsided exclusion rules skew those individual odds, and no draw method can undo that.

The methods we did not take. Sattolo's algorithm is the popular one, above. Two more look correct and are not: resampling only the position that broke the rule, and fixing the fixed points by swapping self-draws away. Martínez–Panholzer–Prodinger is a real alternative rather than a mistake — exactly uniform, linear time, no rejection — passed over because it needs careful ratio arithmetic, overflows double precision past about 170 people, and saves 1.7 shuffles. The exclusion-rules guide has the verified counts.

What is actually inside a link

The decoder above is the checkable version of this section. A Quick link carries a version byte, a 16-byte key, a 12-byte initialisation vector, then the ciphertext and its 16-byte tag, base64url-encoded after the #. Inside sits a small frame: version, flags, a four-byte draw ID, then five length-prefixed fields — opener, recipient, event, note, hint. A fresh key and vector per link mean one going astray costs exactly one assignment.

The frame is then padded with zeros to a constant length, and that padding is load-bearing rather than tidy. AES-GCM does not change the length of what it encrypts, so without padding a link's length minus a known constant is the recipient's name length. On a twelve-name roster that alone narrows 176,214,841 candidate draws to a few hundred and recovers several pairings exactly, with nothing opened and no key used — straight past the interstitial the rest of the design rests on. Every link in one draw is padded to a single length taken from the longest name in the roster, and a test asserts they come out byte-identical.

So link length does not grow with the group: a Quick link is the same length for four people as for fifty — about 200 characters, and identical for everyone in one draw. The exact figure depends on your longest name plus the event and note, never on the size of the group. A Locked reveal link is 263, a participant code 92, a keep link 161. What scales is the number of messages, which is why the generator prints "25 people means 25 separate messages". The comparison guide prices that against the alternatives.

Two modes, and how to pick one

Quick draw is one round with no prerequisites: type names, seal, send. Nobody is blocked because one person did not set themselves up, and the ceiling is the organizer's row above.

Locked draw adds a round first. Each participant opens the key maker on their own device, keeps the link it gives them, and sends back a 92-character code; every envelope you then hand out is sealed to that person's key. The cost is real: everyone has a job before the draw can happen, and someone who loses their keep link needs a fresh one. In twelve people, expect one.

Delegation is the third answer and needs no cryptography: hand the draw to somebody who is not playing, with a roster link carrying names and rules but no pairing, because none exists yet. The catch is that your delegate must be able to message everybody, and in a family draw that is usually a participant. The guides cover all three.

Frequently asked questions

Is a Secret Santa generator safe to use?
It depends on what the generator needs from you. Most ask for everyone's email address, and that list then sits on a server beside the pairings. Sealed Draw asks for names and nothing else, draws in your browser, and gives you one sealed link per person to send yourself. Four questions settle most of it for any tool: does it want email addresses, does it work offline, is there an admin page that can show the results, and is the promise a policy or a property of how it is built?
Can the organizer see who drew whom?
In a Quick draw this tool has no screen, button, or export that shows the organizer who drew whom, and no database that could. What we will not claim is that the organizer cannot look: they hand out every link, so they could open one, deliberately, one at a time, past a screen with someone else's name on it. A sealed envelope, not a vault. In a Locked draw each assignment is sealed to a key the recipient's own device made and sent to nobody. Even then the draw runs in the organizer's browser, so an organizer watching with developer tools open at that instant sees the pairing.
Does anything I type get sent to Sealed Draw?
No. Nothing you type is transmitted by this site, and the whole draw runs with your wifi switched off. There is no account, no database, and no server of ours to store anything on. Two things sit outside that. Chrome's Enhanced Spell Check (behaviour as of August 2026) can send the contents of a text box to Google; that is browser level, underneath our page, so our own meter cannot see it and our Content-Security-Policy cannot stop it, which is why the names box has spell-checking off. An extension can read any page you have open, including this one, and no policy we write reaches it.
What happens to a sealed link after I send it in Slack or WhatsApp?
The chat app stores it, the same way it stores every other message, and it will still be there in February. That is the honest edge of the storage claim: no server of ours holds anything, but the carrier you chose holds the message, and deleting it is their job. Link previews are not the problem, because the sealed part sits after the hash and preview fetchers never send that part to a web server. In a Quick draw the key travels inside the link, so whoever holds that message can open that one assignment.
How do I know the draw is actually random?
The draw is a uniform random derangement: every pairing your rules allow is equally likely, and for ten people with no exclusions that is all 1,334,961 of them. The method is rejection sampling on a Fisher-Yates shuffle driven by your browser's cryptographic random number generator, published because its distribution can be stated in one line. The familiar shortcut of shuffling everyone into a circle cannot produce the three four-person draws where two pairs simply swap, and at twenty people it reaches about one valid draw in seven.

Related