open-standards/wai/live-conformance/watermark
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science aafbf8e1d6 wai.live.watermark: the corpus, its second implementation, the CI step and the changelog
live-conformance/watermark/vectors.json from wai_live_watermark_vectors, and
live_watermark_verify.py, written from the extension's text, which agrees on every
vector, fails every mutated copy and catches a verifier that leaves out any one of
its checks.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 08:40:15 -04:00
..
README.md wai.live.watermark: the corpus, its second implementation, the CI step and the changelog 2026-10-20 08:40:15 -04:00
vectors.json wai.live.watermark: forensic watermark session records, recovered sequences and disclosures (L14) 2026-10-20 08:35:51 -04:00

live-conformance/watermark — forensic watermark sessions

The corpus of extensions/forensic-watermark.md §12, in one file, vectors.json: three rooms, ETSI TS 104 002 watermark tokens, lists of WWS1 session records with or without their tokens, WWQ1 recovered sequences matched against records, and WWD1 disclosures, each with the outcome the extension gives it.

  • rooms: each room's WRD1 descriptor, its WRG1 grants, its key-log head (or null) and its WRE1 confidentiality record (or null), as hexadecimal; broadcast (an origin whose key log lists two edges with live/watermark, a relay with live/relay alone and a revoked edge; region pin DE, FR; retention 30 days), keyless (no origin; its clock is its edge) and e2ee (end-to-end encrypted). A vector names its room and may carry a room_override, whose members replace the room's.
  • tokens: each token's bytes, read by §4.2: read with what it gives (§4.3: cwt_tag, alg, vendor, patlen, source, the clear pattern or null, iat, exp, nbf), or refuse with token_malformed or token_unsupported.
  • sessions: a list of records, each record with its token or null, verified by §9.1: accept with each record's facts (its digest, edge, owner, media, kids, span, vendor, source, patlen, the number of positions served, segments, unmarked, region, expires, and its token's facts or null), or refuse with the reason and the place at: descriptor, key_log, grant and its index, confidentiality, or session and its index.
  • matches: the records and a sequence, by §9.2: matched or unmatched (with no_match or ambiguous_match), and the match: the sequence's digest, the positions it stated, each candidate (its index, digest, whether it agrees, and its first disagreement, a position and unserved or differs), and the matched session or null; or refuse at sequence (or at a record).
  • disclosures: one record with its token, a sequence and a disclosure, by §9.3: accept with its facts (its digest, the session's, the sequence's, the grant, the principal, the positions stated, and token_given), or refuse with the reason and at.

A verifier that reaches another outcome, reason, place or fact does not conform.

Provenance. Generated here: wai_live_watermark_vectors gen writes vectors.json from records authored in code, from fixed seeds. Every key is SHA-256 of a fixed label and an index (principals lists them); every pattern, salt, KID and copy digest is SHA-256 of a label and an index; every time is a constant (the rooms' t0 is 2026-10-18T00:00:00Z); every origin is an .example name (RFC 2606); and Ed25519 signing is deterministic (RFC 8032), so the file is the same bytes on every machine. The tokens are COSE_Mac0 under HMAC 256/256 keyed by wmt_key, which no verifier checks (§4.4); an encrypted pattern is a COSE_Encrypt0 or COSE_Encrypt of the right shape whose bytes no verifier opens. Nothing here was recorded from a deployment.

Checks. wai_live_watermark_vectors verify and tests/live_watermark.rs (wai-rs, feature live_watermark) regenerate the file byte for byte and give every vector its outcome; the generator asserts that every reason of §11 appears. ../live_watermark_verify.py is the second implementation, written from the extension's text: it shares no code with wai-rs, reads rooms with ../live_rooms_verify.py, reads tokens with a CBOR reader of its own, mutates copies of the corpus and requires each to fail, and drops each of its own checks in turn and requires the corpus to catch the weakened verifier.

python3 -I live_watermark_verify.py watermark