open-standards/wai/live-conformance/age
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science 1a8c1a5ead age assurance: one scope per room (live-rooms §10.4) refused by name otherwise, window redemption contexts, admission by the room's service over HTTP, ratings over MOQT
live-rooms §10.4's subscribing scopes did not fit the 255 bytes draft-ietf-moq-privacy-pass-auth-03
gives one MoQAuthorizationInfo: the room's scope is now one MoQAuthScope, the subscribing
actions on MATCH_PREFIX of [R] and on every track name, 78 bytes. A challenge's origin_info is
read by its binding: over MOQT the room's scope byte for byte (scope_malformed, scope_mismatch,
the previous revision's scopes among them); over HTTP RFC 9577's list of server names holding
the service's own. The corpus gains the scope and HTTP cases and RFC 9578 A.2's issuance, which
both verifiers check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 16:15:15 -04:00
..
README.md age assurance: one scope per room (live-rooms §10.4) refused by name otherwise, window redemption contexts, admission by the room's service over HTTP, ratings over MOQT 2026-10-21 16:15:15 -04:00
vectors.json age assurance: one scope per room (live-rooms §10.4) refused by name otherwise, window redemption contexts, admission by the room's service over HTTP, ratings over MOQT 2026-10-21 16:15:15 -04:00

live-conformance/age — age assurance

The corpus of extensions/age-assurance.md §12, in one file, vectors.json:

  • principals: each Ed25519 key, by name (informative);
  • issuer_keys: the three issuer keys of the policies, each its source, issuer, threshold and key (RFC 9578 §6.5's SubjectPublicKeyInfo, hexadecimal), informative;
  • rfc9578_a2_vector1: RFC 9578 Appendix A.2's first test vector, as published: pkI, token_challenge, the client's nonce, its blind r and its PSS salt, the token_request and token_response of its issuance, and the token, in hexadecimal. A conforming verifier finds that the token's challenge_digest is the SHA-256 of token_challenge, its token_key_id the SHA-256 of pkI, and its authenticator s a valid RSASSA-PSS signature under pkI (RFC 9578 §6.4); and that the issuance holds (§6.1 to §6.3 there, RFC 9474 §4.2 to §4.4): the request's blinded message is (s·r)^e mod n, and the response s·r mod n. A client of the issuance protocol reproduces token_request and token from the others;
  • admission_logs: admission logs by name, each a list of admissions, t (room-clock microseconds), challenges (the TokenChallenges the relay sent that session, hexadecimal) and token (hexadecimal);
  • cases: each a name, an about, a kind (one of §9.1's), its inputs, and expect, what a verifier gives it.

Every record is a JSON text (§2). A room's records are hexadecimal: a descriptor, grants and chains (each chain a list of WEV1 records), and key_log (null throughout), as the live-rooms corpus gives them.

Cases. By kind:

  • ratings: claims, rating claims. expect: accept with claims, each its link, signer, subject (the subject's type), age and derived (1 for a claim with inputs, 0 otherwise); or refuse at ["claim", i].
  • admission: a room descriptor, an age policy, the session's challenges, the nonces redeemed, a token, the age required and the binding's origin: null over MOQT, where a challenge's origin_info is the room's scope of live-rooms §10.4, or the service's server name over HTTP (§5.6), where it is RFC 9577's list of server names. expect: accept with the issuer, the threshold and the key_id the token admits under; or refuse at ["policy"] or ["token"].
  • serving: a room descriptor, a track of it (namespace, a list of its fields, and name), claims, and requests, each a threshold, a group and held, the indexes of the claims the relay holds when it serves the request. expect: accept with the track's digest and, for each request, the group's age and its outcome, serve or refuse with the reason; or refuse at ["claim", i].
  • predicate: a sink's anchor (each key's issuer, threshold and key), its credentials (tokens, hexadecimal), the claims it holds, and objects, each a position: a content_hash, a track digest and a group, any of them null. expect: accept with the sink's state and, for each object, its age and verdict, present or withhold.
  • receipt: a room descriptor, an age policy, a receipt, and admissions: the name of an admission log, or null for none. expect: accept with the receipt's link and its cells (each window, issuer, threshold, admitted and suppressed); or refuse at ["policy"], ["admission", i] or ["receipt"].
  • room: a room. expect: accept with the room's own outcome (room_outcome, accept or gap), meets_profile (1 or 0), each grant's thresholds in the order given, and the minor_grants that took effect, each a grant digest in the merged order; or refuse at ["room", …] with the room verifier's own place (["room", "record", c, i] for record i of chain c), ["grant", i] or ["record", c, i].

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

Provenance. Generated here: wai_age_assurance_vectors gen writes vectors.json from records authored in code, from fixed seeds. Every Ed25519 key is SHA-256 of a fixed label; every time is a constant (the rooms' t0 is 2026-10-21T00:00:00Z); every content hash, token nonce, redemption context and RSASSA-PSS salt is SHA-256 output of a fixed label; and Ed25519 signing is deterministic, so the file is the same bytes on every machine. The issuer keys are published test keys whose private keys are published with them: RFC 7517 Appendix A.2's RSA key (threshold 13), RFC 9500 §2.1's testRSA2048 (16) and RFC 9578 Appendix A.2's issuer key (18), each written as RFC 9578 §6.5's SubjectPublicKeyInfo; the generator signs each token's input with the key directly, the signature the blind protocol would also yield. rfc9578_a2_vector1 is that RFC's vector as printed. The challenges over MOQT carry the room's scope of live-rooms §10.4, and the refused ones the scopes of the revision before it, or a scope broken one way; those over HTTP carry room.example, the corpus's service. The rating schemes, their values and the issuers are .example names (RFC 2606) and a tag: URI written for the corpus: no scheme here is any classification body's, and nothing in the corpus states what any content deserves. No recorded data.

python3 -I ../age_assurance_verify.py .