open-standards/wai/live-conformance/e2ee/README.md
2026-10-19 20:54:09 -04:00

4.1 KiB

live-conformance/e2ee — end-to-end encrypted rooms

The corpus of extensions/confidentiality.md §14: rooms whose media objects are sealed as MoQ secure objects under keys from one MLS group per room.

Files

  • vectors.json, written by joule_moq_e2ee_vectors gen:
    • records: confidentiality records (WRE1, §3), each with the room id, the authority's key and the descriptor's recording mode it is checked against, and its outcome: accept with its suite, or the reason of §3.3;
    • key_schedule: for an epoch's application secret, a sender's leaf and a track, the track base key, the KID, the Serialized Full Track Name, moq_key and moq_salt (§4.2, §4.5, §5.7), in both suites and at the KID's limits;
    • objects: sealed objects. A sealed one states its input (the application secret, epoch, leaf, track, Group ID, Object ID, priority, payload, whether it carries an inner digest, padding, other encrypted entries, other Immutable Properties), every derived value (track base key, KID, Full Track Name, key, salt, Immutable Properties, plaintext, AAD, nonce), the object as a -22 object carries it (its property list and sealed payload, hexadecimal), and its content_hash, the BLAKE3 hash a receipt commits to. The negatives are controls of one defect each. Each is opened by the receiver its context names and has its outcome: opened with the BLAKE3 hash of its original payload, or a reason of §6;
    • rooms: transcripts, each a list of steps (a lifecycle event, the group's create, a proposal, a commit with its sender's leaf, the indexes of the epoch's proposals it holds and the new epoch's application secret, or an object with its deliveries), and the outcome a replay gives it (§5.4 to §5.6, §6): accept or refuse with the reason and the step, each epoch's roster, and each delivery's outcome;
    • codes: the reasons of §13, in its order.
  • rfc9605.json: RFC 9605 Appendix C, its header, AES-CTR with HMAC, and SFrame encryption vectors.
  • secure-objects-01.json: draft-ietf-moq-secure-objects-01 Appendix B, its Full Track Name, key derivation, nonce and AAD, and encryption vectors.

Equivalence. A conforming implementation gives every record, object and delivery its outcome, every room its outcome, rosters and deliveries, and every key schedule entry and derived value the bytes stated; it reproduces RFC 9605's vectors, and secure objects' exactly in suites 0x0004 and 0x0005, with the difference §11.2 states in 0x0001 and 0x0002.

The boundary. Each epoch's application secret is given, standing for MLS-Exporter("wai live e2ee", room_id, 32) (§5.7); everything after it is checked. That a real MLS group exports them, and that its rosters are the replay's, is checked by joule-moq-mls's tests, which run the groups.

Provenance. Generated here: joule_moq_e2ee_vectors gen writes vectors.json from rooms authored in code, from fixed seeds: every key is an Ed25519 key whose seed is SHA-256 of wai:e2ee/corpus/key, a zero byte and a label; every application secret SHA-256 of wai:e2ee/corpus/secret, a zero byte, the room's label, the generation and the epoch; every payload SHA-256 in counter mode over wai:e2ee/corpus/bytes and a label; the room id SHA-256 of wai:e2ee/corpus/room and a label. AES-GCM and Ed25519 signing are deterministic, so the file is the same bytes on every machine. No recorded data. rfc9605.json and secure-objects-01.json are the test vectors those documents print, copied with the whitespace inside each value removed and each document's numbers as JSON numbers; nothing in them is generated here.

Checking

cd joule-code/joule-code-rs
cargo run -p joule-moq-mls --bin joule_moq_e2ee_vectors verify ../../wai/live-conformance/e2ee
cargo test -p joule-moq --features secure-objects
cargo test -p joule-moq-mls

cd wai
python3 -I live-conformance/e2ee_verify.py live-conformance/e2ee

e2ee_verify.py is the second implementation, written from the text with the standard library alone; it writes AES and GCM itself, for these vectors only.