AI Computer Institute
Expert-curated CS & AI curriculum aligned to CBSE standards. A bharath.ai initiative. About Us

Watermarking AI-Generated Content: Detection and Attribution

📚 Programming & Coding⏱️ 28 min read🎓 Grade 12
✍️ AI Computer Institute Editorial Team Updated: August 2026 CBSE-aligned · Peer-reviewed · 28 min read
Content curated by subject matter experts with IIT/NIT backgrounds. All chapters are fact-checked against official CBSE/NCERT syllabi.

In April and May 2024, during India's general election campaign, morphed video clips put words into the mouths of two of Bollywood's biggest stars — footage in which they appeared to criticize the incumbent government, circulated widely on WhatsApp before Mumbai Police registered cases and platforms began pulling the clips down. Neither actor had said any of it. The Ministry of Electronics and Information Technology had already issued an advisory in March 2024 asking platforms to label "synthetically generated information," and the deepfakes arrived as almost a live test of exactly the failure mode that advisory anticipated: by the time a fake is identified and reported, it has usually already done its damage, and takedown depends entirely on someone recognizing, by eye, that a video is fake in the first place.

Watermarking asks a narrower, more tractable question than "is this real?" — can an AI system be made to leave behind a signal, in the pixels, in the word choices, in a cryptographically signed file header, that survives long enough for someone holding the right tool to get a statistically confident yes-or-no answer to "did an AI model produce this"? That is detection. A related but distinct question — which model, which version, whose account — is attribution. This chapter builds the actual mechanism behind both, starting with text, where the mathematics is cleanest and fully within reach of what you already know about hashing and the normal distribution.

What a watermark actually is — and the misconception to drop before we start

Classical digital watermarking predates generative AI by decades: hide information in a signal below the threshold of human perception, by flipping the least significant bits of pixel values or nudging frequency-domain coefficients after a transform, so that a specific decoder recovers a hidden payload — a copyright ID, a timestamp — while the eye sees no difference at all. Watermarking for AI-generated content borrows the same instinct but changes what carries the signal. Instead of hiding a payload inside an already-finished image or document, the mark is embedded during generation itself, by biasing the very process that decides which token or which pixel value gets produced next.

Common misconception: most students picture an AI watermark as something visible and removable — a translucent stock-photo-style logo, or the "Generated by AI" caption a chatbot sometimes appends underneath its own answer. That is not what a research-grade content watermark is. The green-list scheme built below, and Google DeepMind's SynthID, alter the statistical distribution of the content itself — a small, deliberate bias in which words a language model prefers, or which pixel values a diffusion model settles into — that is imperceptible to a human reader or viewer and only recoverable by a specific detection algorithm, usually gated by a secret key. Cropping a corner off an image or deleting a caption does nothing to it, because there was never a visible tag sitting there to remove. This distinction also explains the watermark's real weakness, covered later in this chapter: since the signal lives in the statistics of the content rather than in a discrete external tag, any transformation that disturbs those statistics enough — paraphrasing a passage of text, aggressively recompressing and recropping an image, or simply regenerating the same content with a second, unwatermarked model — can wash the signal out even though nothing was "removed" in the way a logo could be cropped away.

Statistical watermarking for text: the green-list method

The scheme below is the one introduced by Kirchenbauer, Geiping, Wen, Katz, Miers and Goldstein in "A Watermark for Large Language Models" (ICML, 2023), and it is the backbone of every green-list-style text watermark deployed since. At every generation step, an LLM has computed a full distribution — logits over its vocabulary V — for the next token, exactly as covered in the Grade 11 transformer-internals unit. Before sampling, the watermarking layer inserts four extra steps:

1. Take the token (or a short window of the last few tokens) the model just emitted, and combine it with a secret key k known only to whoever will later run detection.
2. Hash that combination and use the hash to seed a pseudorandom number generator (PRNG).
3. Use the seeded PRNG to shuffle the candidate vocabulary and cut off a fixed fraction γ (commonly 0.25–0.5) as the "green list"; the rest is the "red list."
4. Add a constant δ to the logits of every green token before applying softmax, then sample as usual.

This is the "soft" watermark: it nudges the sampling distribution toward green without forbidding red tokens outright. A "hard" variant restricts sampling to the green list only, which watermarks more strongly but can force awkward phrasing whenever every fluent continuation happens to land on the red side. Because the green/red split is a deterministic function of nothing but the previous token and the key, whoever holds the key can recompute the exact same split later, on a completely different machine, without the generation process having logged anything extra. That is the entire trick: the signal is never stored — it is reconstructible on demand.

Detection reverses the process. Given a candidate text of T tokens, walk through positions i = 1 … T−1 (the very first token has no predecessor to hash, so it is skipped), recompute the green list at each position from token i−1 and the key, and check whether the actual token at position i lands in it. Call the total number of hits |s|G. Under the null hypothesis that the text was not produced under this watermark — ordinary human writing, or output from a model that never applied δ — each token lands in its (pseudorandom, context-dependent) green list purely by chance, with probability γ, independent of what a human or unwatermarked model would naturally choose to write. So |s|G behaves like a Binomial(T, γ) variable, with mean γT and variance (1−γ). The test statistic

z = (|s|GγT) / √((1−γ))

is, by the normal approximation to the binomial (valid for the token counts real production text runs to), approximately standard normal under the null. Watermarked text, pushed toward green at nearly every step, produces |s|G far above γT and hence a large positive z. Kirchenbauer et al. flag text as watermarked at z > 4, which — since P(Z > 4) ≈ 3.2×10⁻⁵ for a standard normal — keeps the false-positive rate (wrongly flagging genuinely human or unwatermarked text) below roughly 1 in 30,000, at the cost of occasionally missing short genuinely-watermarked passages where sampling noise keeps |s|G closer to the mean.

Worked example: planting and recovering the signal

The toy system below implements the exact same four-step pipeline end to end, on a tiny eight-word vocabulary small enough to inspect by hand, but faithful to the real mechanism: a SHA-256 hash seeds the green/red split, sampling is biased toward green, and detection recomputes the split independently. Every line below was actually executed; the printed values are the real output, not illustrative numbers.

import hashlib, random, math

WORDS = ["the", "rover", "moved", "scanned", "sent", "signal", "reached", "faded"]
TRANSITIONS = {
    w: [WORDS[(i + 1) % 8], WORDS[(i + 2) % 8], WORDS[(i + 3) % 8], WORDS[(i + 4) % 8]]
    for i, w in enumerate(WORDS)
}
KEY = 15485863   # secret key shared by generator and detector
GAMMA = 0.5      # fraction of each candidate set assigned to the green list

def green_list(prev_token, candidates, key=KEY, gamma=GAMMA):
    seed_material = f"{key}-{prev_token}".encode()
    seed = int(hashlib.sha256(seed_material).hexdigest(), 16) % (2**31)
    rng = random.Random(seed)
    shuffled = candidates.copy()
    rng.shuffle(shuffled)
    cut = max(1, round(len(shuffled) * gamma))
    return set(shuffled[:cut])

def generate(start, length, watermark, rng_seed):
    rng = random.Random(rng_seed)
    tokens = [start]
    for _ in range(length - 1):
        prev = tokens[-1]
        candidates = TRANSITIONS[prev]
        if watermark:
            green = green_list(prev, candidates)
            # 90% of draws restricted to the green sublist (soft +delta bias);
            # 10% still draw from the full candidate set
            pool = sorted(green) if rng.random() < 0.9 else candidates
        else:
            pool = candidates
        tokens.append(rng.choice(pool))
    return tokens

def detect(tokens, key=KEY, gamma=GAMMA):
    green_hits, scored = 0, 0
    for i in range(1, len(tokens)):
        prev, cur = tokens[i - 1], tokens[i]
        green = green_list(prev, TRANSITIONS[prev], key, gamma)
        scored += 1
        if cur in green:
            green_hits += 1
    z = (green_hits - gamma * scored) / math.sqrt(scored * gamma * (1 - gamma))
    return green_hits, scored, z

wm_tokens = generate("the", 40, watermark=True, rng_seed=7)
human_tokens = generate("the", 40, watermark=False, rng_seed=7)

print("watermarked:", detect(wm_tokens))
print("baseline   :", detect(human_tokens))

# Output:
# watermarked: (37, 39, 5.60448538317805)
# baseline   : (23, 39, 1.12089707663561)

Trace the detector's arithmetic by hand against that printed output, for the watermarked run: T = 39 scored positions, γ = 0.5, |s|G = 37. Mean under the null: γT = 0.5 × 39 = 19.5. Variance: (1−γ) = 39 × 0.5 × 0.5 = 9.75, so the standard deviation is √9.75 ≈ 3.1225. Then z = (37 − 19.5) / 3.1225 = 17.5 / 3.1225 ≈ 5.604 — matching the printed value exactly. For the unwatermarked baseline, run through the same four numbers with |s|G = 23: z = (23 − 19.5) / 3.1225 = 3.5 / 3.1225 ≈ 1.121, again matching. Converting both to one-tailed p-values under the standard normal: P(Z > 5.604) ≈ 1.0×10⁻⁸, an outcome that would essentially never occur by chance — the text is flagged with overwhelming confidence. P(Z > 1.121) ≈ 0.131 — nowhere near any conventional significance threshold, so the baseline is correctly left unflagged. Notice that 59% of the baseline's tokens (23/39) still happened to land green purely by chance, close to the 50% you'd expect from an unbiased coin flip over 39 draws — the watermark's entire signal is the gap between that chance rate and the far higher rate the biased sampler produces.

How the mechanism looks end to end

Green-List Token Watermarking — Embedding and Detection GENERATION — embedding the signal while sampling each token previous token(s) + secret key k SHA-256(prev, k) → seed PRNG green list (γ·|V|) red list ((1−γ)·|V|) example split at γ = 0.5 add +δ to logits of every green-list token softmax + sample → next token emitted token is appended and becomes the new "previous token" for the next step DETECTION — recomputing the same green lists from a suspect text suspect text T tokens at each position i, recompute green_i from token i−1 and key k — identical rule used at generation tally hits |s|_G = Σ 1[tokenᵢ ∈ greenᵢ] z = (|s|_G − γT) / √(Tγ(1−γ)) standard normal under the null z > 4 ? (p ≈ 3×10⁻⁵) yes no flagged: watermark detected in this text no signal found watermark not confirmed WORKED EXAMPLE — T = 39 scored tokens, γ = 0.5 (see code above) bar length is proportional to green-token count out of 39; distance past the dashed line is the z-score's numerator null mean γT = 19.5 watermarked text 37/39 green (94.9%) z = 5.604 → p ≈ 1.0×10⁻⁸ (flagged) baseline (no watermark) 23/39 green (59.0%) z = 1.121 → p ≈ 0.131 (not flagged) 0 39 tokens scored

Pixels and waveforms: SynthID and the frequency-domain approach

Image, audio and video watermarks embed the same idea — an imperceptible, statistically recoverable bias — on a different substrate, and detection works differently because there is no discrete token sequence to hash. For diffusion models, the watermark is embedded by nudging the sampling or decoding trajectory — which specific pixel intensities the model settles into as it denoises — in a way invisible to the eye. Rather than a closed-form statistical test like the green-list z-score, recovery uses a trained detector network that has learned the specific perturbation pattern. Google DeepMind's SynthID, first deployed on Imagen-generated images via Vertex AI in August 2023 and later extended to text (Dathathri et al., "Scalable watermarking for identifying large language model outputs," Nature, 2024) and to audio and video, is the most widely deployed system in this family. Its perturbation is spread across the whole image in the frequency domain rather than concentrated in one spot, which is what lets it survive common transformations — JPEG recompression, resizing, cropping, screenshotting, colour adjustment — that would defeat a watermark hidden only in a corner or in the least significant bits of a few pixels. Because the detector model itself is not published, third parties generally cannot verify a SynthID mark independently; they submit the file to a checker Google operates.

Provenance without touching a single pixel: C2PA

A cryptographic provenance record takes the opposite approach: instead of altering the content, it attaches a signed manifest — "Content Credentials" under the C2PA standard (the Coalition for Content Provenance and Authenticity, formed in 2021 by Adobe, Microsoft, the BBC, Intel, Truepic and others) — describing which tool created the file, when, whether AI was involved, and a hash chain of every edit since. Verification is signature-checking, not statistics: no z-score, no false-positive rate to reason about, and the pixels or tokens themselves are never touched, so there is zero quality cost. The weakness is the mirror image of a watermark's strength: the credential lives in file metadata, and metadata is trivially stripped by a screenshot or a re-save through almost any ordinary photo app, whereas a pixel- or token-level statistical watermark, in principle, survives exactly that kind of casual re-encoding because the signal is baked into the content, not attached beside it.

Breaking the signal: the paraphrase attack

Krishna, Song, Karpinska, Wieting and Iyyer's NeurIPS 2023 paper "Paraphrasing evades detectors of AI-generated text" makes the text watermark's vulnerability concrete: run the watermarked output through a second, independent paraphrasing model — they train an 11-billion-parameter paraphraser called DIPPER for the purpose — before publishing it. Trace why this defeats the green-list detector using exactly the mechanism from the worked example above: at detection time, the green list at position i is recomputed from whatever token actually sits at position i−1 in the text being checked. Once the paraphraser has swapped out most of the original tokens, the token now sitting at i−1 usually has nothing to do with the token the original watermarked model chose there — so the recomputed green_i has nothing to do with the bias that was actually applied when the original token at position i was sampled. The correlation between "was pushed toward green" and "is green under the recomputed context" collapses; |s|G drifts back down toward the null mean γT, and z falls toward zero, the same way the baseline text in the worked example scored z = 1.121 rather than 5.604. The attacker needs no knowledge of the key and no awareness that a watermark even exists — paraphrasing for entirely mundane reasons, such as translation or a style rewrite, has the identical effect as a side consequence. This is why text watermarking is generally considered the least robust of the three approaches covered in this chapter, and why production systems increasingly stack more than one signal — watermark, provenance metadata, and a separately trained stylometric classifier — rather than relying on any single layer.

Detection, attribution and provenance are three different claims

Detection is binary and statistical: does this content carry the fingerprint of AI generation at all, from any model that shares the relevant key? Attribution goes further — which specific model, and in deployments where the key or watermark parameters are unique per model version or per API account, which specific source — a claim that requires the watermarking scheme to be parameterized differently across models in the first place; a positive match against one provider's key set rules out every other provider's key set, the same way two different SHA-256 keys in the worked example above would produce two completely uncorrelated green/red splits over the same text. Provenance is a different kind of claim again: an auditable history of every recorded editing step since creation, via signed metadata, independent of whether AI was involved at any stage.

One asymmetry is worth internalizing carefully, because it is where students most often overreach: a negative detection result is weak evidence, while a positive one is strong. Absence of a watermark match could mean the content is genuinely human-made, or that it came from a model that never watermarks its output, or that a real watermark was present and destroyed by paraphrase, aggressive re-encoding, or regeneration through a second model — exactly the attack traced in the previous section. Only a positive match is strong evidence, and even then it is evidence only of "generated by a model sharing this key," not "generated by this exact model," unless the deployment ties keys to individual model versions.

India's regulatory push: labelling synthetic content

MeitY's March 2024 advisory, and the subsequent draft amendment to the IT Rules, 2021, on labelling "synthetically generated information," pushes intermediaries toward something closer to the C2PA path than the green-list path — visible or embedded declarations for AI-generated content above a certain scale — precisely because a signed provenance record is auditable by a regulator or platform without needing model-specific detector access, unlike a statistical watermark, which only whoever holds the key can check. The tradeoff carried over from the sections above is the policy's tradeoff too: metadata labels are easy to strip, so a labelling requirement alone catches careless resharing — exactly the WhatsApp-forward pathway the Bollywood deepfakes travelled through — but not a determined actor willing to re-encode a file specifically to remove the declaration. That gap is precisely why serious deployments combine watermarking, provenance metadata, and platform-side detection classifiers, rather than treating any one of the three as sufficient on its own.

Active recall

Attempt every question before reading the answers below it.

1. Why must the green/red vocabulary split be reproducible from the previous token and a key, rather than genuinely random at each generation step?
2. A detector scores a 100-token suspect text with γ = 0.5 and finds |s|G = 68. Compute the z-score by hand.
3. Rerun the worked example's code end to end with only GAMMA changed from 0.5 to 0.25 (same KEY, same rng_seed=7) — the green list is now just 1 of each candidate set's 4 options instead of 2. Because GAMMA also controls the sampling pool inside generate(), this produces a genuinely different 40-token sequence, not the same one rescored — in fact it degenerates into a repeating three-token cycle ("the", "sent", "signal") once the green pool narrows to a single candidate. Running detect() on that new sequence gives |s|G = 37 out of T = 39 — coincidentally the same hit count as the γ = 0.5 run, but on different text. Recompute the null mean, the null standard deviation, and z for this γ = 0.25 case, and explain in words why a smaller γ makes each individual green hit more informative even though the raw hit count happens to match the γ = 0.5 case here.
4. If an attacker paraphrases watermarked text with a second, unwatermarked LLM before publishing it, what happens to the detector's z-score, and precisely why, in terms of the recomputed green lists?
5. A newsroom runs a suspicious image through a SynthID checker and gets "no watermark detected." Can they conclude a human made the image? Justify your answer.
6. Why might a platform deploy both statistical watermarking and C2PA provenance metadata on the same content, rather than choosing one?

Answers

1. If the split were freshly random every time, whoever built the model at generation time could bias sampling toward "green," but nobody at detection time could recover which tokens had been green, since there would be no way to regenerate the same split from just the finished text. Seeding the split from the previous token plus a fixed key makes it a deterministic function that both generation and detection can compute independently and get an identical answer, without either side needing to store anything beyond the key.

2. Mean under the null: γT = 0.5 × 100 = 50. Variance: Tγ(1−γ) = 100 × 0.5 × 0.5 = 25, so standard deviation = √25 = 5. z = (68 − 50) / 5 = 18 / 5 = 3.6. Note this clears typical significance thresholds (P(Z > 3.6) ≈ 1.6×10⁻⁴) but falls short of Kirchenbauer et al.'s conservative z > 4 flagging bar — illustrating that the choice of threshold is itself a precision/recall tradeoff, not a fixed law.

3. New null mean: γT = 0.25 × 39 = 9.75. New variance: Tγ(1−γ) = 39 × 0.25 × 0.75 = 7.3125, so the new standard deviation is √7.3125 ≈ 2.7042. z = (37 − 9.75) / 2.7042 ≈ 27.25 / 2.7042 ≈ 10.08 — nearly double the γ = 0.5 case's z of 5.604, even though the raw green-token count (37) happens to be identical, because the two runs generated different token sequences (γ = 0.25 changes the sampling pool at every step of generation itself, not just the detector's arithmetic). The reason the smaller γ still yields the sharper signal: at γ = 0.25, landing in the green list by pure chance is rarer (only 25% of tokens qualify instead of 50%), so any given hit count is far more surprising under the null hypothesis, and the null standard deviation also shrinks (fewer "typical" outcomes cluster near a lower mean). This is the real tradeoff behind choosing γ in a production system: a smaller γ makes detection more powerful per token, but it also pushes the sampler harder away from its natural top choices at every step (since a smaller fraction of the vocabulary is eligible for the +δ boost) — visible above in how the γ = 0.25 run's sequence degenerated into a repeating three-token loop, which tends to hurt output fluency.

4. z falls sharply toward zero, because paraphrasing swaps out most of the tokens, so the token now sitting at each position i−1 in the published text usually is not the token the original watermarked model actually emitted there. The detector still recomputes green_i correctly from whatever token happens to be at i−1 now — but that recomputed green list has no relationship to the +δ bias that was applied when the original (now-replaced) token at position i was sampled. The correlation the whole scheme depends on is broken, |s|G reverts to roughly γT by chance, and z lands near the baseline case's 1.121 rather than the watermarked case's 5.604.

5. No. A negative result only means this particular check found no match for this particular key — not that no AI was involved. The image could be human-made, but it could equally have come from a model that doesn't watermark its output at all, or have been watermarked and then had the signal destroyed by cropping, heavy recompression, or an editing pipeline that regenerates pixels. Detection is asymmetric: a positive match is strong evidence of AI involvement; a negative result is weak evidence of anything.

6. The two mechanisms fail differently, so combining them raises the bar for an attacker rather than leaving a single point of failure. C2PA metadata is fast and deterministic to check but trivially stripped by a screenshot or re-save; a statistical watermark survives that kind of casual re-encoding because it is baked into the content itself, but it can be washed out by a deliberate paraphrase or regeneration attack, as shown in question 4. An attacker who wants to defeat both simultaneously has to both strip the metadata and successfully launder the statistical signal — a meaningfully harder bar than defeating either mechanism alone, which is precisely the logic MeitY's labelling push and platform-side watermarking are converging toward together rather than as substitutes for each other.

Think About It

Think about this: How would you explain watermarking ai-generated content: detection and attribution to a friend who has never seen a computer? What real-world analogy would you use? Imagine you had to build a system using these concepts — what would be your first step? Try this: before moving on, write down three things you learned and one question you still have.

Practice Exercises

Now it is time to practice! Complete these challenges to solidify your understanding:

  • Exercise 1: Write a short program that demonstrates the core concept from this chapter. Test it with at least 3 different inputs.
  • Exercise 2: Find a real-world example where watermarking ai-generated content: detection and attribution is used in an Indian company (like TCS, Infosys, Flipkart, or ISRO). Write a paragraph explaining the connection.
  • Exercise 3: Create a mind-map connecting watermarking ai-generated content: detection and attribution to at least 3 other topics you have studied.

Key Takeaways — Summary and Recap

Let us recap what we covered: the core ideas behind watermarking ai-generated content: detection and attribution, how they connect to real-world applications, and why they matter for your journey in computer science. Remember these key points as you move forward. For competitive exam preparation (CBSE, JEE, BITSAT), focus on understanding the WHY behind each concept, not just the WHAT.

← AI Red Teaming Methodology: Finding System VulnerabilitiesAI and Biosecurity: Governance, Policy, and Institutional Oversight →

Found this useful? Share it!

📱 WhatsApp 🐦 Twitter 💼 LinkedIn