Pseudorandom Number Explorer
How simulation software makes “random” numbers – inspectable arithmetic, judged on uniformity and independence
© 2026 Theodore P. Pavlic · MIT License
A pseudorandom number generator (PRNG) is a short arithmetic recipe whose outputs are judged on two separate properties: uniformity (the values fill [0, 1] evenly) and independence (knowing one value tells you nothing about the ones that follow). For one stream (i.e., the sequence u₁, u₂, … that one choice of parameters and seed produces), the panels below judge uniformity and independence separately, and the verdicts can disagree. From the preset list below, the Toy example amplifies the effect: its 16 possible outputs appear equally often, and yet a conspicuous pattern relates past values to future values. The Toy pattern is effectively embedded in every stream below, but most are dense enough to hide it; RANDU, also in the preset list, appears independent until you look across the triples it produces. Despite these inevitable patterns in PRNGs, their repeatability can be leveraged to reduce extra sources of variance in experiments and to increase reproducibility when sharing experimental results.
Linear congruential generator (LCG)
These numbers pin down the whole stream: anyone who uses the same parameters and seeds gets exactly the same sequence.
Walk through an LCG output step by step
The panels below read the outputs u in table order; seed rows are not emitted.
Stream for both panels – u₁ … un, n = 500
Property 1: Uniformity – do the values fill [0, 1] evenly?
▮ observed density   ┄ uniform density = 1 · grow the stream and watch the bars flatten
χ² statistic = χ² p-value =
K–S statistic Dn = K–S p-value =
Property 2: Independence – does one value predict a later one?
Each dot pairs one output with the output k steps later: horizontal position un, vertical position un+k. Lag k = 1 pairs each value with the very next one; a larger lag asks whether a value predicts further ahead. LCGs show a characteristic pattern of parallel stripes when plotted this way, which reflects that they are deterministic processes and not sources of true randomness. The stripe pattern is called the generator's lattice, and this scatter of pairs is a lattice plot.
1
independent values would fill the square with structureless noise; any visible pattern is dependence
Why would a simulation want fake randomness?

Determinism is the feature, not the flaw. A simulation whose randomness comes from a seeded recurrence can be reproduced exactly: rerun with the same parameters and seed, and every draw, every queue, and every estimate comes back identical, which is what makes a surprising result checkable and a bug findable. Write down the four numbers on this tab, and any classmate can regenerate your entire stream.

Reproducibility also buys sharper comparisons. To compare two system designs fairly, feed both the same random inputs (the same arrival times, the same service demands) so that any difference in the results is caused by the designs and not by luck. That technique, common random numbers, only exists because the “random” numbers are deterministic.

The price is that the stream is not random at all, and so it has to behave, statistically, like randomness. The two panels above are exactly that audit: the values must fill [0, 1] evenly, and no value may carry usable information about the ones that follow.

What does the recurrence say, and why do all deterministic sequences eventually repeat?

The state is a whole number xn between 0 and m − 1. Each step multiplies by a, adds c, and keeps only the remainder after dividing by m: the “mod” operation, the same wrap-around as a clock face. Dividing the state by m rescales it into [0, 1), which is the un a simulation actually consumes.

Because the next state depends only on the current state, and there are just m possible states, the sequence must eventually revisit a state and from then on repeat exactly. The length of that loop is the generator's period, and it is one reason m is chosen enormous. Try the toy preset (m = 16) and step through the table until it repeats; then consider how far apart the same two states are under the minimal standard.

Which parameter choices guarantee a full period?

For c ≠ 0, the Hull–Dobell theorem (1962) says that the cycle visits all m states from every seed precisely when three conditions hold: (1) c and m share no common factor; (2) every prime that divides m also divides a − 1; and (3) if 4 divides m, then 4 also divides a − 1. The toy preset and the C-standard-style preset both satisfy all three, which is why the toy has a full period of 16.

For c = 0, the state 0 is stuck, and so a full period is impossible; what is attainable depends on m. With m prime, the period is m − 1 from any nonzero seed exactly when a is a primitive root mod m (a special condition from number theory), which is the minimal standard's design. With m a power of two, the best possible is m/4, attained when a ≡ ±3 (mod 8) and the seed is odd; RANDU sits exactly there, with period 2²⁹ = m/4.

What do the two uniformity tests check, and what is the big thing they cannot see?

The chi-square test cuts [0, 1] into k equal bins and compares each observed count with the n/k a uniform distribution would put there; the statistic totals the squared mismatches. The Kolmogorov–Smirnov statistic Dn pushes the same idea to its limit. Sort the values so that the r-th smallest one “should” sit near r/n. Chi-square counts crowding in a few wide bins; K–S in effect cuts a bin so fine that each holds a single point and reports the farthest any point strays from where its rank says it should sit. That farthest stray is exactly the biggest vertical gap between the empirical CDF and the diagonal, marked on the small plot. Both p-values answer the same question: could a mismatch this large plausibly come from truly uniform draws?

Both tests treat the sample as a bag of values – they are not sensitive to the order of the values. Judging whether the order is consistent with independent draws is the job of separate tools: autocorrelation tests, runs tests, and the lattice panel beside the uniformity tests.

What is the lattice in the independence plot, and why does every LCG have one?

Consecutive states of an LCG satisfy xi+1 = (a·xi + c) mod m. Without the mod, every pair (xi, xi+1) would sit on the single straight line y = a·x + c; the mod subtracts some whole multiple of m from y, and so the pair sits on one of the parallel lines y = a·x + c − j·m instead. Dividing by m to get the u values only rescales that picture into the unit square. Pairs of consecutive outputs therefore cannot land just anywhere: they are confined to a family of parallel lines, a lattice. The same argument confines triples of consecutive outputs to parallel planes in three dimensions, and so on in every dimension.

Every LCG has such a lattice; there is no parameter choice that escapes it. The design question is how fine it is. A good multiplier packs the lines so closely that the grain is far below anything a simulation could resolve; a bad one (RANDU is the canonical case) leaves gaps you can see by eye, meaning huge regions of the square, or of the cube, that pairs of “random” values can never visit. George Marsaglia made this pointed observation in a famously titled 1968 paper, “Random numbers fall mainly in the planes” (PNAS 61(1):25–28).

Raising the lag k probes a different slice of the dependence structure: the pairs (un, un+k) obey the k-steps-ahead recurrence, which is itself an LCG whose multiplier is ak mod m, and so a generator can look fine at lag 1 and still show its grain at another.

Combining two LCGs extends the period far beyond either modulus. Although many LCG parameter choices provide good uniformity and independence, an LCG's period can never exceed its modulus, and that is limiting in practice: a modern computational experiment, simulation, or chat session with your favorite LLM draws thousands or even millions of random numbers, and the sequence must not repeat itself along the way. One remedy is to combine two LCGs by taking their sum or difference. Both generators being combined here are plain c = 0 LCGs from tab ①, each with its own modulus; the output is their difference, wrapped mod m₁. The combined stream repeats only after the least common multiple (lcm) of the component periods, the first moment both cycles come back into alignment at once. A CLCG also solves a subtler problem: its output hides its internal state. In an LCG, the output is determined entirely by the current state, and so each output value is always followed by the same pattern because each state is always followed by the same pattern. In a CLCG, the same output value can result from different states of the two LCGs being combined, and so repeated outputs of the same value need not be followed by the same pattern each time.
Combined LCG (CLCG)
These numbers pin down the whole stream: anyone who uses the same parameters and seeds gets exactly the same sequence.
Walk through a CLCG output step by step
Both component streams and the combined stream, side by side; the seed row is not emitted.
Combining LCGs extends the period
The combined state repeats only when both components line up again at the same moment, like two turn signals blinking at different rates or two sustained tones at slightly different pitches making a slow, audible beat: each cycle on its own is short, but the pair realigns only rarely. When the two periods share few factors, the wait is nearly their product.
Combining LCGs adds apparent non-determinism – the same output, different futures
Both squares are lattice plots of consecutive pairs (un, un+1), the same view as the independence panel on tab ①.
component 1 alone: one dot per column – each value fixes its successor
combined: columns hold several dots – the output no longer fixes the future
What is a lead-in, and why is a seed sometimes never revisited?

The next state in an LCG is computed from the current state, and so once any state repeats, everything after it repeats too. Nothing guarantees the repeat reaches all the way back to the seed, though. If the update rule is many-to-one, meaning two different states map to the same next state, then some states have no way of being reached a second time: once the orbit leaves them, they are gone for good. States the cycle keeps returning to are called recurrent; states visited at most once on the way in are called transient; and the steps spent among transient states before the orbit settles onto its cycle are the lead-in the period card reports. Drawn on paper, such an orbit looks like the letter ρ: a short tail flowing into a loop.

A multiplicative component x → a·x mod m is reversible exactly when a shares no factor with m; every state then has a unique predecessor, and every orbit is a pure loop with no lead-in. When a and m share a factor, information is destroyed at each step. With a = 2 and m = 26, for example, the states x and x + 13 collide into the same next state, and after one step, every reachable state is even, and so an odd seed such as 1 can never come back. Well-designed generators choose parameters that keep the update reversible, and so no state is wasted on a tail; RANDU's even seeds falling into shorter cycles (tab ①) are this same phenomenon in another costume.

Does a CLCG's determinism still give it a lattice?

Yes. A CLCG is a deterministic recurrence like any other, and so its pairs of consecutive outputs still cannot land just anywhere. Each component keeps the lattice that every LCG has (tab ①), but the other component's cycle drifts across it, smearing the stripes. Combining does not remove structure so much as fold two structures against each other until neither is visible at any usable scale.

An MRG gets the power of two parallel generators from one generator's own history. The CLCG of tab ② gets its long period by holding two independent states in memory at once: it is, in effect, a generator with two words of memory that happen to live in separate machines. The multiple recursive generator (MRG) reorganizes that memory. Instead of two recurrences that each remember one value, one recurrence remembers its last k values (k is called the order of the recurrence) and combines them to produce the next – a generator bootstrapped on its own recent past. A snapshot of two parallel states and a window of one sequence's recent history hold the same kind of extra information, but the extra information from the recent history can generate an even longer period. With k words of memory, there are mᵏ possible states, and a well-chosen recurrence visits mᵏ − 1 of them before repeating. The last preset below, MRG32k3a, stacks the two ideas (two order-3 MRGs, combined exactly as tab ② combines two LCGs) and is the generator many production simulation tools actually run.
Multiple recursive generator (MRG)
These numbers pin down the whole stream: anyone who uses the same parameters and seeds gets exactly the same sequence.
Walk through an MRG output step by step
The first k rows are the seeds; outputs begin once the recurrence has enough history to reach back to.
How the period grows
Memory sets the ceiling. A generator that remembers only its last value must repeat as soon as that value recurs, and so it can run no longer than m − 1 steps; one that remembers its last k values repeats only when a whole run of k recurs, and a well-chosen recurrence reaches every nonzero run before that happens.
Pairs of consecutive outputs
Why does more memory lengthen the period, what exactly is MRG32k3a, and what are substreams?

A generator that remembers only its last value must repeat as soon as any single value recurs. A generator that remembers its last k values only repeats when a whole run of k values recurs together, and there are mk possible runs. A well-chosen order-k recurrence visits every state except the all-zero one before repeating, for a period of mk − 1. The toy preset shows the jump at a human scale: the same modulus 13 that caps a c = 0 LCG at period 12 supports period 168 = 13² − 1 with just one extra word of memory.

MRG32k3a (L'Ecuyer 1999) is where this tab and tab ② meet: two order-3 MRGs over different moduli, combined by subtraction exactly as the CLCG combines two LCGs, with period about 2¹⁹¹. It is the generator inside many production simulation tools.

MRG32k3a's cycle is not just enormous; it also comes with a jump-ahead operator. Because the recurrence is linear, two applications of it collapse into a single rule of the same small size, and doubling again gives the four-step rule, the eight-step rule, and so on. What gets squared is the step rule itself, never a state, and so 127 doublings build a rule that leaps 2¹²⁷ steps in one application, without producing any of the states in between. Size and jump-ahead together make it possible to divide the one cycle into streams (blocks 2¹²⁷ long) and each stream into substreams (blocks 2⁷⁶ long), each entered by jumping straight to its starting state; only the very first position is ever seeded by hand. In practice, each source of randomness in a simulation gets its own stream, and each replication advances to the next substream within it, which keeps common-random-number comparisons aligned across replications. Every block behaves as an independent generator, with no need to invent a new seed for any of them, and with none of the risk that hand-picked seeds land on overlapping stretches of the same cycle. This stream–substream scheme is from L'Ecuyer et al. (2002, Operations Research 50(6):1073–1075).

Every pseudorandom stream already carries a watermark: its own parameters. To a stranger, an LCG's outputs look uniform and independent. To someone who knows the multiplier, the very same outputs are perfectly dependent because each one pins down the next exactly. Suppose company X ships simulation software whose streams come from an LCG configured one particular way. Checking whether a file of numbers matches that configuration is testing for company X's implicit signature – a watermark nobody had to add, readable only by someone who knows what to test for. This tab reads such a mark; the next tab builds one deliberately.
Reading the implicit watermark of an LCG
The mystery stream comes from xn+1 = a·xn mod 2³¹−1 with a secret multiplier from the list. Pick a candidate: for each step, the plot places what the candidate predicts horizontally and what was actually observed vertically. The right multiplier collapses every point onto the diagonal; a wrong one scatters them over the square, exactly as uniform-and-independent would.
The same stream passes the standard tests
Judged the way tab ① judges any stream, the mystery stream is unremarkable: its histogram is flat, its lag plot shows no visible grain, and the chi-square and K–S tests stay clean (up to the 5% of streams any test falsely flags), whichever multiplier produced it. Nothing about the stream advertises that a signature is there to find; the prediction plot reads the mark only because it is handed the right a to test.
histogram of the 2,000 mystery values
2,000 consecutive pairs from the mystery stream: no visible grain
A watermark nobody had to add. With c = 0 and a known modulus, the state is the output, and so knowing a turns the stream from unpredictable to perfectly predictable: given one output, the possibilities for the next collapse to a single point. Without a, those possibilities stay spread uniformly, which is why the standard tests pass either way. The mark also biases nothing: a wide range of multipliers make equally sound generators, and so company X's choice is as reasonable a generator as any other, and testing for it later is a filter only company X thinks to apply.
Why parameter watermarks are not enough. Reading the mark above worked because an LCG's state is visible in its output. A CLCG or an MRG32k3a has more internal state than it shows: MRG32k3a carries six words behind every single output, and so enormously many internal states produce the same visible value. Even knowing every parameter, you cannot predict the next output from the stream alone, and the implicit watermark becomes unreadable. Every naked generator carries such a mark in its structure and parameters, but how readable the mark is depends on an accident of the design. A deliberate watermark should not rest on an accident – the next tab builds the readability in on purpose.
Pseudorandom number generators can be designed for flexible watermarking by making seeds dependent upon outputs. Tab ④'s mark could be read only because an LCG happens to show its state; a deliberate watermarker does not have to rely on that accident. Instead of letting the generator carry its state forward, throw the state away before every draw and re-seed it with a keyed mix of the last four outputs – a short scramble of the same multiply-and-mix arithmetic as everything else on this page, steered by a secret key (just a whole number). The seed, and so the next value, becomes computable from the visible history by anyone who holds the key and by no one else.
Re-seeding from the visible history
Whereas a CLCG's next output depends on several hidden states at once, an MRG guides its next output with a saved history of one generator's prior values. Build that history from prior outputs instead, and deliberate watermarking becomes possible: every variable that generation needs is observable. Below, the past four outputs are mixed with a secret key to generate each new output (the first four pass through from MRG32k3a), and so whoever holds the key can check whether a stream's recent history is consistent with generation by their PRNG – effectively a cryptographic signature applied on top of the generated numbers. The plot compares what a tested key predicts for each draw (horizontal) with what was observed (vertical); the right key puts every point on the diagonal.
// un is the n-th value the stream emits
// ⊕ is a bitwise, binary XOR operator
h = key
for each q of un−4, un−3, un−2, un−1 (each as ⌊u·232⌋):
  h = (h ⊕ q) · 2654435761 mod 232
sn = (h ⊕ ⌊h/216⌋) mod (231−1)
xn = 16807 · sn mod (231−1)
un = xn / (231−1)
The cost: you have replaced the generator
After the four pass-through draws, MRG32k3a contributes nothing – every later value is fixed by the key and the history, whatever generator sits underneath. The period guarantees, the equidistribution, and the streams and substreams of tabs ①–③ are gone, and the stream's quality now rests entirely on the homemade mix. The watermark and the generator have become a single decision again, only more so: the signature is the generator. What a practical watermark wants is the opposite – keep a well-studied generator intact and lay the mark on top of its outputs. The next tab does exactly that.
Uniform and grainless to everyone else
Without the key, the re-seeded stream is unremarkable: the uniformity tests stay clean (up to the 5% of streams any test falsely flags), and consecutive pairs show no grain. Nothing visible separates it from the streams of tabs ①–③.
histogram of the 2,000 re-seeded values
2,000 consecutive pairs from the re-seeded stream
Detection is all-or-nothing
A re-seeded stream is not merely biased toward its key – it is a deterministic function of it, and so detection is a certificate rather than a statistic. The secret key (top row) predicts every draw; twenty random wrong keys predict none.
bar: the share of draws that key predicts exactly
key confirmed: every draw predicted, which a wrong key manages with probability about 1 in 2.1 × 10⁹ per draw not this key: one missed draw rules it out, and so probing any single key, as at the left, is already a complete test
Watermarking modules can be added to existing PRNGs without modifying them. Re-seeding bought readability by replacing the generator; this tab keeps the generator intact and instead steers which of its outputs get emitted. Any generator could sit underneath – the tournament only ever asks it for draws, never looks inside it, and MRG32k3a plays the part here. The tool is a keyed scoring function – the same kind of keyed mix as the last tab, now turning the key, a round number, the recent history, and a candidate value into a score between 0 and 1. Whoever holds the key can recompute any score; to everyone else, the scores might as well not exist.
A tournament chooses among valid realizations
On the left sits the source distribution – here uniform, from MRG32k3a – whose eight draws seed the bracket, a small sample of the distribution itself. Each round is played by its own keyed rule: under each value sits its score for the round it is about to play, and the higher score of each pairing advances until one survivor is emitted. Edit the key, and the same eight candidates crown a different winner. The embedder at the bottom of this tab runs exactly this tournament for every value it emits, reading its own last four outputs as the history.
Distortion-free on continuous distributions
The tournament never invents a value and never vetoes one: it only chooses among draws the generator underneath (here MRG32k3a) was already willing to make, working inside the diversity the stream already offers. At any one history, the choice genuinely favors the values the keyed rules score highly – that bias is the watermark – but a history of four real numbers essentially never recurs, and so each bias acts exactly once, and across histories the biases point in unrelated directions and cancel: run the tournament for 2,000 draws, and the winners fill [0, 1] as evenly as the generator itself would. Only along the key's own score axis do the biases all point the same way. The same bolting-on works for any source distribution, a pmf over words included, as long as the candidates have spread: a distribution so concentrated that they all agree leaves every key making the same choice and nothing to mark.
How to assign scores in each tournament round
A score is a function of four ingredients – the key, the round, the last four outputs h1…h4, and the candidate u – mixed by the same multiply-mod-2³² arithmetic as the generators on this page. Here ⊕ is bitwise XOR (base-2 addition without carries), and every value in [0, 1] enters as the 32-bit integer ⌊value · 2³²⌋:
// ⊕ is a bitwise, binary XOR operator
h = key ⊕ ((round + 1) · 2654435761 mod 232)
for each q of h1, h2, h3, h4, u:
  h = (h ⊕ q) · 2654435761 mod 232
  h = h ⊕ ⌊h/216
h = (h ⊕ ⌊h/213⌋) · 2246822507 mod 232
h = h ⊕ ⌊h/216
score = h / 232
Changing any ingredient, however slightly, re-rolls the score completely:
Scores for one candidate across keys
u = 0.500 under 400 consecutive keys: flat – whatever value might be emitted, from whatever source distribution, no key is biased for or against it.
Each key scores the candidates differently
The same 400 candidates scored under two keys: horizontal under key A, vertical under key B. Identical keys put every point on the diagonal; keys that differ even by 1 scatter the points uniformly, and so a score under one key says nothing about the score under another. A key never means “prefer these values” (at language scale, “use these words more”); it only reshuffles which candidates happen to score high.
set key B equal to key A to collapse the cloud onto the diagonal
Scores across candidates under key A
The marginal distribution of the scatter's horizontal coordinate: the same 400 candidates' scores under key A alone. Flat, and so no stretch of [0, 1] is favored – and it stays flat whichever key A is.
Every emitted value wins a keyed tournament
Here the tournament from the top of this tab runs for real: whenever a value is needed, eight candidates are drawn from MRG32k3a, the three keyed rules eliminate them pairwise, and the winner is emitted. Emitted values therefore tend to score high under all three rules, and a detector that knows the key averages those scores over the stream: near 0.66 instead of the 0.50 of chance. The two panels below score the same stream twice, once under the secret key and once under whatever other key you type.
Uniformity, independence, and detectability
Below, a PRNG without tournament watermarking is compared to one with a tournament add-on to select watermarked values. Neither a chi-square test nor a Kolmogorov–Smirnov test finds a deviation from uniformity in either stream, up to the 5% of streams any test falsely flags, and the watermarked stream shows no grain in its lag plot below. However, whereas the unmarked stream emits values whose keyed scores average 0.5, which is what chance would give, the watermarked stream emits values whose scores average significantly more than that.
2,000 consecutive pairs from the marked stream: no visible grain
Strong statistical signal for only the secret key
The confidence intervals below summarize testing for 21 different watermarks across the 596 watermarked values generated just above. Testing for the secret key is in the top row, and the remaining 20 rows are 20 randomly drawn keys. Whereas 95% confidence intervals are shown, the type-I error rate α for applying the ✓ mark is far below the usual 0.05 because a deployed detector would test many thousands of streams a day.
one row per key, the secret key in the top row, its tint and symbol carrying its verdict – dot and whiskers: each key's detection mean with its 95% confidence interval
mark detected: z > 6, rejecting chance at α ≈ 10−9 ? weak evidence: 3 < z ≤ 6 (one-sided p between 0.0013 and 10−9) consistent with chance: z ≤ 3 (p above 0.0013)
Why does the tournament change neither the distribution nor the visible independence?

In generation with tournament-style watermarking, distortion is only a problem with repeated histories. A history of four real numbers essentially never recurs, and so each skewed conditional contributes a single draw whose support is unchanged, and nothing accumulates where a histogram could show it. Tab ⑦ is the opposite case – a fourteen-word vocabulary repeats histories constantly – and it enforces the same one-draw rule explicitly, as repeated-context masking.

The watermark does add dependence, but it is routed entirely through the keyed scores. Each emitted value relates to its four predecessors through the scoring rules. Without the key, those scores cannot be recomputed, and lag plots and the other unkeyed diagnostics show nothing; with the key, the detector's average score stands tens of null standard errors clear of chance in a few hundred values. The pattern is there, in the same sense an LCG's lattice is there, and it is just as invisible until you apply the right filter.

A detector needs nothing but the stream and the key. Reading the scoring inputs from the visible outputs, rather than from a hidden counter, makes detection self-synchronizing. The language-model version reads the recent words for the same reason – the text itself is all a detector ever gets.

Watermarking can be added to any random-variate generator, including language models that generate text. A language model's next word is a draw from a probability distribution over its whole vocabulary, and drawing from any distribution starts from a uniform pseudorandom number: line up the words' probabilities along [0, 1], and the draw picks the word whose slice it lands in (the inverse-transform method). A keyed scoring function is just as indifferent: it scores a word's identity the way it scored a candidate number. The tournament therefore runs unchanged – draw eight candidate words from the model's distribution, play three keyed rounds, and emit the winner. That tournament is the published mechanism of Google's SynthID watermark for text (Dathathri et al. 2024, Nature 634:818–823), run here at toy scale. A deployed system differs in many engineering details, but the limits are the same: detection is statistical, and so it needs enough words to stand clear of chance, and editing or paraphrasing the text weakens the signature.
One blank, one tournament
A toy model has reached a blank. Its distribution over the next word (the dashed teal levels) puts most of the probability on a few words and a little on many others, and "New context" reshapes it – a new context ranks new words highly, exactly as the language model at the right does at every word. The last four words of the context are the watermark's history, labeled below, and the table beneath the chart lists every word's three round scores for exactly this history. A tournament has already been played – the winner (the highlighted column) fills the blank, usually a word that scores well across the rounds and always a legitimate draw – and running one more draws eight fresh candidates for the same blank. The bracket beneath the chart plays the whole tournament out.
Risks and mitigation for distortion by watermarking. With the same fixed history, the key distorts the distribution in a consistent, key-specific way, and "Run 2,000 tournaments" with "Mask repeated contexts" turned off reveals how severe an impact the tournament has on the distribution of emitted tokens. However, the longer the history window, the rarer it will be to encounter the exact same history multiple times in a generated passage, and other sequences in the history window will lead to different watermarking biases across the dictionary of possible words. Furthermore, in real implementations of this style of watermarking, only the first encounter with a particular string of prior words triggers watermarking of the next emitted token, and so when there are numerous cases of repeated context windows (which can be frequent with short history windows), the watermarking distortion is diluted, not reinforced. By selecting "Run 2,000 tournaments" with "Mask repeated contexts" turned on, the emitted histogram matches the desired one despite the first instance being watermarked and thus drawn from a distorted distribution.
This run's tournament, played out
The eight dots on the pmf are this run's draws – a repeated word stacks its dots – and each word carries its score for the round it is about to play; the higher score of each pairing advances, and the winner's path is picked out in the accent. After "Run 2,000 tournaments", the bracket shows run 1, which with masking on is the only run that was watermarked.
Every word's scores at this blank
The whole vocabulary, one row per word – not a sequence of draws. The rows are sorted by model probability only to match the chart above; a word's scores come from the keyed rules and have nothing to do with its probability.
Watermarking a tiny language model
A word-level Markov chain writes whole passages. The blank at the left froze one context of a toy model; here the model is trained on the corpus below, and it reshapes its distribution at every word: some contexts offer many continuations, and some force exactly one. Three extra bits of state – has this clause had its verb, is a fronted phrase still waiting for its comma, is a subordinate clause still open – keep every sentence a sentence, the same more-state cure tab ③'s recurrences used.
The same tournament rides on top. Eight candidates drawn from the current context's own distribution, three keyed rounds, one winner emitted – and a repeated four-word history passes through unmarked, exactly as at the left.
The chain order sets how much room the watermark has. Order 1 barely remembers and barely constrains, and so nearly every word offers the key a real choice; order 3 reproduces the corpus faithfully and forces most continuations, leaving the key little to do. The stats under the passage keep score, and the distribution check compares the passage against the chain's own conditionals – marked or not, about 5% of testable contexts should be flagged at the 5% level.
Read the training corpus first – the chain should be judged against it, not against an LLM
Reading the watermark back
A detector needs only the text and a candidate key. It recomputes each fresh-context word's three round scores from the visible words alone – no access to the chain or the generator – and pools them into one mean per key. The lineup tests the secret key (the top row) against twenty random wrong keys, key at the left, mean at the right, whiskers a 95% confidence interval. Wrong keys hug the dashed 0.5 of chance, the key that marked the passage stands clear, and an unwatermarked passage leaves every key at chance – a single score proves nothing under any key (the table at the left looks just as random under the right key), and so a longer passage means tighter whiskers and surer verdicts.
one row per key, the secret key in the top row, its tint and symbol carrying its verdict – dot and whiskers: each key's detection mean with its 95% confidence interval
mark detected: z > 6, rejecting chance at α ≈ 10−9 ? weak evidence: 3 < z ≤ 6 (one-sided p between 0.0013 and 10−9) consistent with chance: z ≤ 3 (p above 0.0013)
A 95% confidence interval (the whiskers above) fails to cover the true mean in 5% of experiments. Detection is one-sided, though – only a mean above 0.5 counts – and so only half of those misses can read as detections: in a lineup of twenty wrong keys, an interval lands entirely above 0.5 about once every other redraw. Even that is far too often for a detector scanning millions of documents a day, and so the bar for ✓ sits at α ≈ 10−9 rather than 0.05, far more conservative than the plotted intervals.
There is no green list: no word is favored, and no word is shunned. An earlier family of watermarks (Kirchenbauer et al. 2023, ICML) really does keep a keyed “green list” of words, boosted before every draw – a push that continues even where the model is nearly certain. The tournament keeps no list, and none could exist: scored by rule 1 across 2,000 synthetic four-word contexts each, three words from the toy vocabulary come out flat on [0, 1] – dragons, the vocabulary's long shot, included – and rules 2 and 3, and every other key, behave identically. Although watermarking induces a preference for words with higher scores at any one blank, a word's score varies across the text, and so the overall distribution of words in the text is not shifted toward any watermarking-favored words as it would be with green or red lists.
The watermark lives in predictability, not in preferred phrases. Text generation is one blank after another, and each choice reshapes the model's distribution for the next blank. Every emitted word is drawn from that reshaped distribution, and so the forward pass stays consistent, and a low-probability word almost never even reaches the bracket. The key does not prefer “at last” after “lingered”: its scores change with every context, and so no phrase is favored overall, and every word keeps its long-run rate. What the key adds is a slight predictability – the emitted word tends to score highly among the likely options at its blank. Where one word dominates, as at the last blank below, every key crowns that same word, and so the mark accumulates only where the model leaves real alternatives: forced text such as a quotation or a formula carries almost no signature, however long it runs.
Why mask repeated contexts at all?

Because a bias that acts once is invisible, and a bias that acts twice is the same bias twice. The winner of a single tournament is still a word the model offered, and one draw cannot reveal which conditional produced it; the repeat demo above shows what surrendering that safety costs. Masking turns the safety into a rule – each four-word history gets its tournament at most once per text – and the detector, computing the same mask from the same visible words, skips exactly the same positions. How often the rule bites depends on the vocabulary: in this widget's 230-word world, a third of the words in a few pages land on a used history, whereas in a real model's hundred-thousand-word vocabulary exact four-word repeats are rare outside genuinely repetitive text – the very text where a repeated bias would otherwise pile into a visible pattern.

Tab ⑥ never needed the rule spelled out: its histories are four real numbers, which essentially never recur, and so every bias acts once by itself. The principle on both tabs is the same – work inside the diversity the source already offers, spend each history's bias at most once, and let the biases cancel everywhere except along the key's own score axis, where they all point the same way.