draft-zink-xboundary · live sandbox

AI-generated text watermarking & public key DNS record verification

This demo allows you to do the following: (a) Watermark a piece of text, (b) verify it against a key published in DNS, (c) build a _watermark-text DNS record — a public key for an asymmetric scheme, or a k=symmetric record plus its §6.6 verification document — or (d) lint (verify the syntax) of every record a domain publishes.

Two algorithms for demonstration purposes. tzsataitw-1 (zero-width characters) and tzsataitw-2 (look-alike letters) are steganographic short-text marks — easily stripped by normalisation, but they demonstrate that you can put a signature into a piece of text that can be verified with a public key.

Two algorithms for actual watermarking. fairoze-1 is the publicly-detectable [Fairoze23] construction (Ed25519 variant) — unforgeable, but needs ~700+ words and breaks on almost any edit. synthid-1 is SynthID-Text [Dathathri24], a symmetric statistical mark: there is no public key, so DNS publishes a k=symmetric record whose d= document names a verify endpoint the key holder runs. For both, the samples here are pre-generated — the text was independently generated on an open-weight model with the watermark inserted at that time. It's computationally expensive, which is why it's not done on-the-fly in this demo, and you cannot paste in your own text.

tzsataitw-* and fairoze-1 demonstrate the asymmetric verify-via-DNS loop — you'd generate your own key pair, publish the public key in a DNS record, and keep the private key secret. synthid-1 shows the symmetric variant, where verification runs through the provider's own endpoint rather than a public key. Signing here uses dedicated demo keys.

Watermark text

Paste in some text below (this demo doesn't generate it the way an LLM does). One of this server's demo keys will hide and sign the 64-byte signature inside it. The signature covers "<algorithm>\n" + canonical_text — never the locator.

Each key signs one fixed algorithm — the one its _watermark-text record publishes in a=. It is not selectable here: signing with a different algorithm would just fail verification.