#!/usr/bin/env python3 """Independent reference for the packages of several components (extensions/packaging.md §4.5 and §5.8), over pack-conformance/multi/. Written from the extension text. It shares no code with wai-pack, which writes the corpus. It takes BLAKE3 from ../claim-conformance/_blake3.py and Ed25519 verification from ../claim-conformance/_ed25519.py, and renders vector graphics with ../tools/wai_vector_check.py, each written from its own specification. From each golden's inputs alone (its policy, its committed sources, the stereo WAV of the formula below, and the lead's plan file) it recomputes, for every component beside the lead: - its pieces: the lead's starts and end converted to its timebase (§4.5), against its stage index's piece records, each flagged aligned to the lead; - each base's decoded-output digest (§6.5, §5.8), from the source, never from the package's objects: the SHA-256 of the WAV's interleaved s16le samples of the piece; of the score's mixdown of the piece (one channel, or two interleaved), by the reference synthesis of score.md §3, its voices included, in the Fx floor written here; the clip digest of the source document's frames of the piece at its first listed size and the component's rate (graphics-vector §3.1, P7); the SHA-256 of the WebVTT segment of the piece (timed-text §5.2), written here; and zero for a feed; - each object's bytes where §5.8 fixes them from the source: the FLAC of each audio piece and of each score piece's mixdown, by the encoder §5.8 defines, written here; each text piece's segment, and its target, the component's language and the piece's span; and each object named by its content hash; - each feed piece's seal: its final tick, and its signature by the receipt's key; - graphics-vector §6: each graphics piece is its source's window slice byte for byte (§6.1) and has its source's document digest (§6.2); its text floor is its transcript in the raw Zstandard frame, under the manifest that presents its base (§6.3); and the caption rule (§6.4) holds on the sources and on the package's own pieces and segments. It then plants a fault in a copy of each golden, one per component, and requires the recomputation to find it; and, for graphics-vector §6, faults that keep a piece consistent in every other respect, each of which its own check must find and which the recomputation must take with that check left out. python3 -I multi_verify.py Exit status 0 only if every golden holds and every planted fault is found. """ import hashlib import importlib.util import json import math import os import struct import sys import tomllib HERE = os.path.dirname(os.path.abspath(__file__)) def _load(name, path): spec = importlib.util.spec_from_file_location(name, path) m = importlib.util.module_from_spec(spec) spec.loader.exec_module(m) return m B3 = _load("_blake3", os.path.join(HERE, "..", "claim-conformance", "_blake3.py")) ED = _load("_ed25519", os.path.join(HERE, "..", "claim-conformance", "_ed25519.py")) WVC = _load("wai_vector_check", os.path.join(HERE, "..", "tools", "wai_vector_check.py")) GOLDENS = ["multi-av-01", "multi-titles-01", "multi-feed-01", "multi-sting-01", "multi-opus-01", "multi-captions-01"] FLAG_ALIGNED = 8 def sha256(b): return hashlib.sha256(b).digest() def le(b, at, n): return int.from_bytes(b[at:at + n], "little") # ---------------------------------------------------------------- the stage index (§6.2) def read_index(b): n_p, n_e = le(b, 16, 4), le(b, 20, 4) pieces = [{"start": le(b, 160 + 32 * k, 8), "dur": le(b, 168 + 32 * k, 4), "first": le(b, 172 + 32 * k, 4), "n": le(b, 176 + 32 * k, 2), "kind": b[178 + 32 * k], "flags": b[179 + 32 * k]} for k in range(n_p)] at = 160 + 32 * n_p entries = [] for k in range(n_e): e = b[at + 128 * k:at + 128 * (k + 1)] entries.append({"hash": e[0:32], "len": le(e, 32, 8), "role": e[54], "tier": e[56], "digest": e[64:96]}) return {"media": le(b, 6, 2), "tb": (le(b, 8, 4), le(b, 12, 4)), "pieces": pieces, "entries": entries} def payload_of(env): """A WAI1 envelope's payload: `WAI1`, u32 manifest length, the manifest, u32 payload length, the payload.""" assert env[:4] == b"WAI1" ml = le(env, 4, 4) pl = le(env, 8 + ml, 4) assert len(env) == 12 + ml + pl return env[12 + ml:] def manifest_of(env): """A WAI1 envelope's manifest, as JSON.""" return json.loads(env[8:8 + le(env, 4, 4)]) def content_hash(env): return B3.blake3(b"moq-jwp:object\x01" + env) # ---------------------------------------------------------------- §4.5 def align(units, lead, tb): return units * tb[0] * lead[1] // (tb[1] * lead[0]) def spans(lead_starts, lead_end, lead, tb): at = [align(s, lead, tb) for s in lead_starts] + [align(lead_end, lead, tb)] return [(at[i], at[i + 1] - at[i]) for i in range(len(lead_starts))] # ---------------------------------------------------------------- the WAV (multi_fixture) def wav_sample(k, c): if c == 0: return ((k * 7) % 400) * 80 - 16000 t = k % 200 return (t * 300 if t < 100 else (200 - t) * 300) - 15000 def s16le(samples): return b"".join(struct.pack("> i) & 1) self.n += 1 if self.n == 8: self.out.append(self.acc) self.acc, self.n = 0, 0 def unary(self, q): for _ in range(q): self.put(0, 1) self.put(1, 1) def align(self): while self.n: self.put(0, 1) def crc8(b): c = 0 for x in b: c ^= x for _ in range(8): c = ((c << 1) ^ 0x07) & 0xFF if c & 0x80 else (c << 1) & 0xFF return c def crc16(b): c = 0 for x in b: c ^= x << 8 for _ in range(8): c = ((c << 1) ^ 0x8005) & 0xFFFF if c & 0x8000 else (c << 1) & 0xFFFF return c def coded_number(v): if v < 0x80: return bytes([v]) for n, lead, lim in ((2, 0xC0, 0x800), (3, 0xE0, 0x10000), (4, 0xF0, 0x200000), (5, 0xF8, 0x4000000), (6, 0xFC, 1 << 31)): if v < lim: return bytes([lead | (v >> (6 * (n - 1)))] + [0x80 | ((v >> (6 * i)) & 0x3F) for i in range(n - 2, -1, -1)]) raise ValueError(v) def fixed_residual(x, i, order): return [x[i], x[i] - x[i - 1], x[i] - 2 * x[i - 1] + x[i - 2], x[i] - 3 * x[i - 1] + 3 * x[i - 2] - x[i - 3], x[i] - 4 * x[i - 1] + 6 * x[i - 2] - 4 * x[i - 3] + x[i - 4]][order] if order <= 4 else None def subframe(w, x): n = len(x) best, best_bits = None, None for order in range(5): if order >= n: break u = [(r << 1) if r >= 0 else ((-r) << 1) - 1 for r in (fixed_residual(x, i, order) for i in range(order, n))] p, bits = min(((p, sum(1 + p + (v >> p) for v in u)) for p in range(15)), key=lambda t: (t[1], t[0])) total = 8 + 16 * order + 10 + bits if best_bits is None or total < best_bits: best, best_bits = (order, p, u), total if best is None or 8 + 16 * n < best_bits: w.put(0x02, 8) for s in x: w.put(s & 0xFFFF, 16) return order, p, u = best w.put((0b001000 | order) << 1, 8) for s in x[:order]: w.put(s & 0xFFFF, 16) w.put(0, 2) w.put(0, 4) w.put(p, 4) for v in u: w.unary(v >> p) w.put(v & ((1 << p) - 1), p) def flac(samples, ch, rate, block=4096): frames = len(samples) // ch w = Bits() w.out += b"fLaC" w.put(0x80, 8) w.put(34, 24) w.put(block, 16) w.put(block, 16) w.put(0, 24) w.put(0, 24) w.put(rate, 20) w.put(ch - 1, 3) w.put(15, 5) w.put(frames, 36) w.put(0, 128) for k, start in enumerate(range(0, frames, block)): n = min(block, frames - start) at = len(w.out) head = bytes([0xFF, 0xF8, 0x70, ((ch - 1) << 4) | 0x08]) + coded_number(k) + (n - 1).to_bytes(2, "big") w.out += head + bytes([crc8(head)]) for c in range(ch): subframe(w, [samples[i * ch + c] for i in range(start, start + n)]) w.align() w.out += crc16(bytes(w.out[at:])).to_bytes(2, "big") return bytes(w.out) # ---------------------------------------------------------------- the score, score.md §3 I64_MAX, I64_MIN = (1 << 63) - 1, -(1 << 63) ONE, HALF, QUARTER = 1 << 32, 1 << 31, 1 << 30 SAW, SQUARE, TRIANGLE, PULSE25, SAW_BL, SQUARE_BL, PULSE25_BL, SINE, NOISE = range(9) SINE_P = 966367642 # 0.225 in Q32.32, rounded (§3.2) VOICE = struct.Struct("> 32) def fdiv(a, b): if b == 0: return I64_MAX if a >= 0 else I64_MIN return sat((a << 32) // b) def neg(a): return I64_MAX if a == I64_MIN else -a def fabs(a): return neg(a) if a < 0 else a def fsqrt(a): """The profile's square root: the floor square root of the raw bits times 2^32, and 0 for a value of 0 or below.""" return 0 if a <= 0 else math.isqrt(a << 32) def wrap(p): return sat(p - ONE) if p >= ONE else p def blep(t, dt): """The polynomial correction at phase t of a step at phase 0, at increment dt (§3.2).""" if dt <= 0: return 0 if t < dt: x = fdiv(t, dt) return sat(sat(sat(x + x) - fmul(x, x)) - ONE) if t > sat(ONE - dt): x = fdiv(sat(t - ONE), dt) return sat(sat(sat(fmul(x, x) + x) + x) + ONE) return 0 def osc(phase, kind, dt, held): if kind == SAW: return sat(fmul(2 * ONE, phase) - ONE) if kind == SQUARE: return ONE if phase < HALF else -ONE if kind == TRIANGLE: return sat(fmul(4 * ONE, phase) - ONE) if phase < HALF else sat(3 * ONE - fmul(4 * ONE, phase)) if kind == PULSE25: return ONE if phase < QUARTER else -ONE if kind == SAW_BL: return sat(sat(fmul(2 * ONE, phase) - ONE) - blep(phase, dt)) if kind == SQUARE_BL: naive = ONE if phase < HALF else -ONE return sat(sat(naive + blep(phase, dt)) - blep(wrap(sat(phase + HALF)), dt)) if kind == PULSE25_BL: naive = ONE if phase < QUARTER else -ONE return sat(sat(naive + blep(phase, dt)) - blep(wrap(sat(sat(phase + HALF) + QUARTER)), dt)) if kind == SINE: u = sat(fmul(2 * ONE, phase) - ONE) y = fmul(fmul(4 * ONE, u), sat(ONE - fabs(u))) y = sat(fmul(SINE_P, sat(fmul(y, fabs(y)) - y)) + y) return neg(y) if kind == NOISE: return held return 0 class Osc: """A note's phase, and its noise generator: s <- 1664525 s + 1013904223 (mod 2^32), its top 24 bits held as a value in [-1, 1) until the phase wraps.""" def __init__(self, seed): self.phase, self.lcg = 0, seed self.draw() def draw(self): self.lcg = (self.lcg * 1664525 + 1013904223) & 0xFFFFFFFF self.held = ((self.lcg >> 8) - (1 << 23)) << 9 def advance(self, dt, kind): self.phase = sat(self.phase + dt) if self.phase >= ONE: self.phase = sat(self.phase - ONE) if kind == NOISE: self.draw() def adsr(t, n): """The linear ADSR of a score with no voices (§3.1).""" if n["attack"] > 0 and t < n["attack"]: return fdiv(t << 32, n["attack"] << 32) ad = n["attack"] + n["decay"] if t < ad: return sat(ONE - fdiv(fmul(sat(ONE - n["sustain"]), (t - n["attack"]) << 32), n["decay"] << 32)) if n["decay"] > 0 else n["sustain"] if t < n["dur"]: return n["sustain"] if n["release"] > 0 and t < n["dur"] + n["release"]: return fmul(n["sustain"], sat(ONE - fdiv((t - n["dur"]) << 32, n["release"] << 32))) return 0 def frac(t, n): return (t << 32) // n def curve(v, k): r = v for _ in range(1, k): r = fmul(r, v) return r def held_level(t, n, v): """A voiced note's attack, decay and sustain (§3.3).""" if n["attack"] > 0 and t < n["attack"]: return sat(ONE - curve(sat(ONE - frac(t, n["attack"])), v["attack_curve"])) td = t - min(n["attack"], t) if n["decay"] > 0 and td < n["decay"]: return sat(n["sustain"] + fmul(sat(ONE - n["sustain"]), curve(sat(ONE - frac(td, n["decay"])), v["decay_curve"]))) return n["sustain"] def voiced_env(t, n, v, off): if t < n["dur"]: return held_level(t, n, v) tr = t - n["dur"] if n["release"] > 0 and tr < n["release"]: return fmul(off, curve(sat(ONE - frac(tr, n["release"])), v["release_curve"])) return 0 def pan_gains(p): return fsqrt(sat(ONE - p) >> 1), fsqrt(sat(ONE + p) >> 1) def put(buf, two, i, x, gains): if two: buf[2 * i] = sat(buf[2 * i] + fmul(x, gains[0])) buf[2 * i + 1] = sat(buf[2 * i + 1] + fmul(x, gains[1])) else: buf[i] = sat(buf[i] + x) def render_plain(buf, two, duration, n): centre = pan_gains(0) o = Osc(0) for i in range(n["start"], min(n["start"] + n["dur"] + n["release"], duration)): x = fmul(fmul(osc(o.phase, n["waveform"], n["phase_inc"], o.held), adsr(i - n["start"], n)), n["gain"]) put(buf, two, i, x, centre) o.advance(n["phase_inc"], n["waveform"]) def render_voiced(buf, two, duration, n, v): gains = pan_gains(v["pan"]) echo, level = [], ONE for j in range(1, min(v["echo_taps"], 8) + 1): level = fmul(level, v["echo_gain"]) echo.append((level, pan_gains(v["echo_pan"] if j % 2 == 1 else neg(v["echo_pan"])))) poles = min(v["lp_poles"], 4) off = held_level(n["dur"], n, v) delta = v["glide_to"] - n["phase_inc"] o = Osc(v["seed"]) y = [0] * 4 for i in range(n["start"], min(n["start"] + n["dur"] + n["release"], duration)): t = i - n["start"] dt = n["phase_inc"] if v["glide"] == 0 else sat(n["phase_inc"] + delta * min(t, v["glide"]) // v["glide"]) env = voiced_env(t, n, v, off) x = osc(o.phase, n["waveform"], dt, o.held) if poles: a = min(ONE, max(0, sat(v["lp_a"] + fmul(v["lp_env"], env)))) for k in range(poles): y[k] = sat(y[k] + fmul(a, sat(x - y[k]))) x = y[k] x = fmul(fmul(x, env), n["gain"]) put(buf, two, i, x, gains) for j, (g, eg) in enumerate(echo): at = i + (j + 1) * v["echo_delay"] if at >= duration: break put(buf, two, at, fmul(x, g), eg) o.advance(dt, n["waveform"]) def quant(v): v = max(-ONE, min(ONE, v)) num = v * 32767 return (num + HALF) >> 32 if num >= 0 else -((-num + HALF) >> 32) def read_score(b): """A WSCR's contract, notes and voices (score §2): the voices None in a score of the first revision's two sections.""" assert b[:4] == b"WSCR" n = le(b, 4, 2) sec = {} base = 6 + 9 * n for i in range(n): kind, off, ln = b[6 + 9 * i], le(b, 7 + 9 * i, 4), le(b, 11 + 9 * i, 4) sec[kind] = b[base + off:base + off + ln] contract = json.loads(sec[1]) assert contract["channels"] in (1, 2) nb = sec[2] notes = [] for k in range(le(nb, 0, 4)): f = struct.unpack_from(" b0) # ---------------------------------------------------------------- captions (graphics-vector §6.4) def cue_text(blk): """A cue's text from the cue as §5.1 writes it: the lines after its timing line, separated by U+000A, the tags of §5.1 (italics, a label) removed and its three escapes read back.""" import re body = blk.rstrip("\n").split("\n", 1)[1] if "\n" in blk.rstrip("\n") else "" body = re.sub(r"<[^>]*>", "", body) return body.replace("<", "<").replace(">", ">").replace("&", "&") def segment_cues(seg): """The cues of a §5.2 segment: (start, end, text).""" head, _, rest = seg.partition("\n\n") assert head.startswith("WEBVTT\nX-TIMESTAMP-MAP=") return [(a, b, cue_text(blk)) for a, b, blk in cue_blocks("WEBVTT\n\n" + rest)] if rest.strip() else [] def merge_captions(lists): by = {} for caps in lists: for lang, text, shown in caps: by.setdefault((lang, text), []).extend(tuple(x) for x in shown) return [[lang, text, WVC.merge_ms(v)] for (lang, text), v in sorted(by.items())] def caption_rule(captions, tracks): """Graphics-vector §6.4: for every language among a graphics component's caption intervals, one text component of that language (`tracks`: (lang in ASCII lower case, cues)) on which every string's cues, merged, are its intervals. None when it holds, and what does not otherwise.""" for lang in sorted({c[0] for c in captions}): mine = [t for t in tracks if t[0] == lang] miss = None for _, cues in mine: bad = [c for c in captions if c[0] == lang and WVC.merge_ms([(a, b) for a, b, text in cues if text.encode() == c[1] and a < b]) != c[2]] if not bad: break miss = miss or "cues of %r in %s are not shown over %r ms" % (bad[0][1].decode(), lang.decode(), bad[0][2]) else: return miss or "no text component in %s" % lang.decode() return None # ---------------------------------------------------------------- an Opus floor (§7.9) def opus_samples(p): """The samples at 48 kHz an Opus packet lasts (RFC 6716 §3.1), the packet held to §3.4's R1 to R7; None for a packet that breaks one.""" if not p: return None toc = p[0] cfg = toc >> 3 frame = [480, 960, 1920, 2880][cfg % 4] if cfg < 12 else ([480, 960][cfg % 2] if cfg < 16 else [120, 240, 480, 960][cfg % 4]) n = len(p) def flen(at, end): if at >= end: return None if p[at] < 252: return p[at], 1 if at + 1 >= end: return None return p[at + 1] * 4 + p[at], 2 code = toc & 3 if code == 0: return frame if n - 1 <= 1275 else None if code == 1: return 2 * frame if (n - 1) % 2 == 0 and (n - 1) // 2 <= 1275 else None if code == 2: r = flen(1, n) if r is None: return None rest = n - 1 - r[1] return 2 * frame if r[0] <= rest and rest - r[0] <= 1275 else None if n < 2: return None vbr, padded, m = p[1] & 0x80, p[1] & 0x40, p[1] & 0x3f if m == 0 or m * frame > 5760: return None at, pad = 2, 0 if padded: while True: if at >= n: return None v = p[at] at += 1 if v == 255: pad += 254 else: pad += v break end = n - pad if end < at: return None if vbr: total = 0 for _ in range(m - 1): r = flen(at, end) if r is None or r[0] > 1275: return None at += r[1] total += r[0] if at > end or total > end - at or end - at - total > 1275: return None elif (end - at) % m or (end - at) // m > 1275: return None return m * frame def ogg_crc(b): c = 0 for x in b: c ^= x << 24 for _ in range(8): c = ((c << 1) ^ 0x04C11DB7) & 0xFFFFFFFF if c & 0x80000000 else (c << 1) & 0xFFFFFFFF return c def ogg_page(flags, granule, seq, packet): lacing = bytes([255] * (len(packet) // 255) + [len(packet) % 255]) head = b"OggS" + bytes([0, flags]) + struct.pack("I4s", b[a:a + 8]) h = 8 if size == 1: size, h = struct.unpack(">Q", b[a + 8:a + 16])[0], 16 if size < h or a + size > z: raise ValueError("a box past its parent") out.append((kind, a + h, a + size)) a += size return out def one(bs, kind): v = [x for x in bs if x[0] == kind] if len(v) != 1: raise ValueError("not one %s" % kind) return v[0] def opus_init(b): """A supplied Opus init.mp4 (§7.9): (track, trex defaults, channels, pre-skip, input rate, gain), or ValueError.""" moov = one(boxes_of(b, 0, len(b)), b"moov") mb = boxes_of(b, moov[1], moov[2]) trak, mvex = one(mb, b"trak"), one(mb, b"mvex") tb = boxes_of(b, trak[1], trak[2]) tkhd = one(tb, b"tkhd") track = int.from_bytes(b[tkhd[1] + (20 if b[tkhd[1]] == 1 else 12):][:4], "big") mdia = one(tb, b"mdia") md = boxes_of(b, mdia[1], mdia[2]) mdhd = one(md, b"mdhd") ts = int.from_bytes(b[mdhd[1] + (20 if b[mdhd[1]] == 1 else 12):][:4], "big") if ts != 48000: raise ValueError("a timescale other than 48000") hdlr = one(md, b"hdlr") if b[hdlr[1] + 8:hdlr[1] + 12] != b"soun": raise ValueError("not a sound track") minf = one(md, b"minf") stbl = one(boxes_of(b, minf[1], minf[2]), b"stbl") stsd = one(boxes_of(b, stbl[1], stbl[2]), b"stsd") ents = boxes_of(b, stsd[1] + 8, stsd[2]) if int.from_bytes(b[stsd[1] + 4:stsd[1] + 8], "big") != 1 or len(ents) != 1 or ents[0][0] != b"Opus": raise ValueError("not one Opus sample entry") e = ents[0] entry_ch = int.from_bytes(b[e[1] + 16:e[1] + 18], "big") d = one(boxes_of(b, e[1] + 28, e[2]), b"dOps") o = b[d[1]:d[2]] if len(o) != 11 or o[0] != 0 or o[10] != 0: raise ValueError("not a dOps of version 0 and mapping family 0") ch, skip, rate, gain = o[1], int.from_bytes(o[2:4], "big"), int.from_bytes(o[4:8], "big"), int.from_bytes(o[8:10], "big", signed=True) if ch not in (1, 2) or ch != entry_ch: raise ValueError("channels") for x in tb: if x[0] == b"edts": el = one(boxes_of(b, x[1], x[2]), b"elst") v = b[el[1]] cnt = int.from_bytes(b[el[1] + 4:el[1] + 8], "big") if v == 1: mt, r = int.from_bytes(b[el[1] + 16:el[1] + 24], "big", signed=True), int.from_bytes(b[el[1] + 24:el[1] + 28], "big") else: mt, r = int.from_bytes(b[el[1] + 12:el[1] + 16], "big", signed=True), int.from_bytes(b[el[1] + 16:el[1] + 20], "big") if cnt != 1 or mt not in (0, skip) or r != 0x10000: raise ValueError("an edit list other than one entry at media time 0 or the pre-skip") trex = one(boxes_of(b, mvex[1], mvex[2]), b"trex") t = b[trex[1]:trex[2]] if int.from_bytes(t[4:8], "big") != track: raise ValueError("trex of another track") return track, (int.from_bytes(t[12:16], "big"), int.from_bytes(t[16:20], "big"), int.from_bytes(t[20:24], "big")), ch, skip, rate, gain def opus_segment(b, track, dflt): """A media segment's samples (§7.7's boxes): [(bytes, duration, flags, dts)].""" top = boxes_of(b, 0, len(b)) first = next(i for i, x in enumerate(top) if x[0] == b"moof") if any(x[0] not in (b"styp", b"sidx", b"prft", b"emsg", b"free", b"skip") for x in top[:first]): raise ValueError("a box before the first moof") rest = top[first:] if len(rest) % 2 or any(rest[i][0] != b"moof" or rest[i + 1][0] != b"mdat" for i in range(0, len(rest), 2)): raise ValueError("other than moof and mdat pairs") out, nxt = [], None for i in range(0, len(rest), 2): moof, mdat = rest[i], rest[i + 1] mb = boxes_of(b, moof[1], moof[2]) traf = one(mb, b"traf") tb = boxes_of(b, traf[1], traf[2]) tfhd = one(tb, b"tfhd") tf = int.from_bytes(b[tfhd[1] + 1:tfhd[1] + 4], "big") if tf & ~(0x02 | 0x08 | 0x10 | 0x20 | 0x20000) or int.from_bytes(b[tfhd[1] + 4:tfhd[1] + 8], "big") != track: raise ValueError("tfhd") at = tfhd[1] + 8 vals = [] for bit in (0x02, 0x08, 0x10, 0x20): if tf & bit: vals.append(int.from_bytes(b[at:at + 4], "big")) at += 4 else: vals.append(None) d_dur = vals[1] if vals[1] is not None else dflt[0] d_size = vals[2] if vals[2] is not None else dflt[1] d_flags = vals[3] if vals[3] is not None else dflt[2] tfdt = one(tb, b"tfdt") dts = int.from_bytes(b[tfdt[1] + 4:tfdt[1] + 12], "big") if b[tfdt[1]] == 1 else int.from_bytes(b[tfdt[1] + 4:tfdt[1] + 8], "big") if nxt is not None and nxt != dts: raise ValueError("a moof not where the one before it ended") for trun in [x for x in tb if x[0] == b"trun"]: rf = int.from_bytes(b[trun[1] + 1:trun[1] + 4], "big") n = int.from_bytes(b[trun[1] + 4:trun[1] + 8], "big") data = moof[1] - 8 + int.from_bytes(b[trun[1] + 8:trun[1] + 12], "big", signed=True) at = trun[1] + 12 ff = None if rf & 0x04: ff = int.from_bytes(b[at:at + 4], "big") at += 4 for k in range(n): f = {} for bit in (0x100, 0x200, 0x400, 0x800): if rf & bit: f[bit] = int.from_bytes(b[at:at + 4], "big") at += 4 dur, size = f.get(0x100, d_dur), f.get(0x200, d_size) flags = (ff if ff is not None else f.get(0x400, d_flags)) if k == 0 else f.get(0x400, d_flags) if f.get(0x800, 0) or size == 0 or data < mdat[1] or data + size > mdat[2]: raise ValueError("a sample") out.append((b[data:data + size], dur, flags, dts)) data += size dts += dur nxt = dts return out def opus_floor(pkg, P, name, starts, total, channels): """The Opus floor a package carries (§7.9): its init's fields and its packets [(bytes, samples, dts, segment)], or ValueError naming what does not hold.""" lb = pkg.get("floor.listing") if lb is None or hashlib.sha256(lb).hexdigest() != P["floor"]["supplied_listing"]: raise ValueError("floor.listing does not hash to the policy's supplied_listing") lines = [ln.split(" ", 1) for ln in lb.decode().splitlines()] files = {path: h for h, path in lines} init_name = name + "/init.mp4" segs = sorted((p for p in files if p.startswith(name + "/") and p != init_name), key=lambda x: x.encode()) ib = pkg.get("floor/%s/init.mp4" % name) if ib is None or hashlib.sha256(ib).hexdigest() != files.get(init_name): raise ValueError("floor/%s/init.mp4 is not the supplied init" % name) track, dflt, ch, skip, rate, gain = opus_init(ib) if ch != channels: raise ValueError("channels") packets, durs, nxt = [], [], 0 for si, f in enumerate(segs): b = pkg.get("floor/%s/%s.m4s" % (name, files[f])) if b is None or hashlib.sha256(b).hexdigest() != files[f] or "/" in f[len(name) + 1:] or not f.endswith(".m4s"): raise ValueError("%s is not in the package by its SHA-256" % f) smp = opus_segment(b, track, dflt) if any(x[2] & 0x10000 for x in smp) or smp[0][3] != nxt: raise ValueError("%s: a sample that is not a sync sample, or a gap" % f) for data, dur, _, dts in smp: n = opus_samples(data) if n is None: raise ValueError("%s: a malformed packet" % f) packets.append((data, n, dts, si)) durs.append(dur) nxt = dts + dur if any(d != p[1] for d, p in zip(durs[:-1], packets[:-1])) or not 0 < durs[-1] <= packets[-1][1]: raise ValueError("a sample that does not last its packet") if nxt < total + skip or nxt - durs[-1] >= total + skip: raise ValueError("the packets' length is not the programme's and the pre-skip") tail = len(segs) == len(starts) + 1 if len(segs) not in (len(starts), len(starts) + 1): raise ValueError("not a segment per piece") for data, n, dts, si in packets: want = len(starts) if tail and dts >= total else max(i for i, s0 in enumerate(starts) if s0 <= dts) if si != want: raise ValueError("a packet in another piece's segment") return (ch, skip, rate, gain), packets def opus_object(floor, s, e): """The floor object §7.9 writes for the piece [s, e).""" (ch, skip, rate, gain), packets = floor a = max(0, s + skip - 3840) first = max(i for i, p in enumerate(packets) if p[2] <= a) last = max(i for i, p in enumerate(packets) if p[2] <= e + skip - 1) return ogg_opus([(p[0], p[1]) for p in packets[first:last + 1]], s + skip - packets[first][2], e - s, ch, rate, gain) # ---------------------------------------------------------------- one golden def check_golden(gdir, pkg, fail, skip=(), sources=None): """Every check of a golden; `skip` names checks left out, which the planted faults use to show that each of graphics-vector §6's checks alone finds its fault. `sources` gives a source's bytes by file name in place of the committed file.""" sources = sources or {} P = tomllib.load(open(os.path.join(gdir, "policy.toml"), "rb")) receipt = json.loads(pkg["package.receipt.json"]) lead_id = P["lead"] comps = {c["id"]: c for c in P["component"]} lead_tb = (comps[lead_id]["timebase"]["num"], comps[lead_id]["timebase"]["den"]) lead_ix = read_index(pkg["index-%s.wsix" % lead_id]) lead_starts = [int(x) for x in pkg["plan-%s.txt" % lead_id].decode().split()] lead_end = lead_ix["pieces"][-1]["start"] + lead_ix["pieces"][-1]["dur"] if [p["start"] for p in lead_ix["pieces"]] != lead_starts: fail("the lead's plan is not its index's") rungs = {} for r in P.get("ladder", []): rungs.setdefault(r["component"], []).append(r) # Graphics-vector §6.4: each graphics component's caption intervals, from its source # and from its pieces, and each text component's cues, from its source and its segments. cap_src, cap_pkg, tracks_src, tracks_pkg = {}, {}, [], [] for cid, c in comps.items(): if cid == lead_id: continue tb = (c["timebase"]["num"], c["timebase"]["den"]) ix = read_index(pkg["index-%s.wsix" % cid]) sp = spans(lead_starts, lead_end, lead_tb, tb) if [(p["start"], p["dur"]) for p in ix["pieces"]] != sp or any(p["flags"] != FLAG_ALIGNED for p in ix["pieces"]): fail("%s: its pieces are not the lead's, aligned" % cid) continue if pkg.get("plan-%s.txt" % cid) != "".join("%d\n" % s for s, _ in sp).encode(): fail("%s: its plan file" % cid) objs = [] for e in ix["entries"]: env = pkg.get("objects/%s.wai" % e["hash"].hex()) if env is None or content_hash(env) != e["hash"] or len(env) != e["len"]: fail("%s: an entry's object is not its content hash" % cid) objs.append(None) else: objs.append(env) if None in objs: continue base_cap = next(r["capability"] for r in rungs[cid] if r["role"] == "base") src = None if c["source"].endswith(".wav") else sources.get(c["source"]) or open(os.path.join(gdir, "sources", c["source"]), "rb").read() if base_cap == "wai.audio.score": contract, notes = read_score(src) mix = mixdown(contract, notes) if base_cap == "wai.text.timed": cues = cue_blocks(src.decode()) tracks_src.append((c["lang"].lower().encode(), [(a, b, cue_text(blk)) for a, b, blk in cues])) tracks_pkg.append((c["lang"].lower().encode(), [])) if base_cap == "wai.graphics.vector": doc = WVC.load(src) z = doc.sizes[0] cap_src[cid] = WVC.captions(doc) cap_pkg[cid] = [] # A sound track's Opus floor (§7.9), read from the package's CMAF files through # floor.listing, which the policy pins. floor_cap = next((r["capability"] for r in rungs[cid] if r["role"] == "floor"), None) if base_cap == "wai.graphics.vector" and floor_cap is not None and \ (floor_cap != "wai.text.zstd" or next(r for r in rungs[cid] if r["role"] == "floor").get("params") != {"source": "encode"}): fail("%s: a graphics component's floor rung is wai.text.zstd, encoded (graphics-vector §6.3)" % cid) opus = None if floor_cap == "wai.audio.opus": try: opus = opus_floor(pkg, P, cid, [x for x, _ in sp], sp[-1][0] + sp[-1][1], 2) except (ValueError, StopIteration, KeyError, IndexError, struct.error) as x: fail("%s: its Opus floor: %s" % (cid, x)) continue listing = P["floor"]["supplied_listing"] settings = '{"source":"supplied","supplied_listing":"%s"}' % listing settings_digest = B3.blake3(b"wai:render-settings\x01" + settings.encode()).hex() for k, (s, n) in enumerate(sp): p = ix["pieces"][k] es = ix["entries"][p["first"]:p["first"] + p["n"]] base = payload_of(objs[p["first"]]) want_payload, floor_payload = None, None if base_cap == "wai.audio.flac": pcm = [wav_sample(i, ch) for i in range(s, s + n) for ch in (0, 1)] digest = sha256(s16le(pcm)) want_payload = flac(pcm, 2, tb[0]) if opus is not None: floor_payload = opus_object(opus, s, s + n) # Its manifest: the piece's samples, presenting the piece's base. fm = manifest_of(objs[p["first"] + 1]) if len(es) > 1 else {} df = fm.get("derived_from") or {} if fm.get("target") != {"channels": 2, "rate": tb[0], "samples": n} or \ df != {"motif": es[0]["hash"].hex(), "motif_capability": "wai.audio.flac", "renderer": "supplied@" + listing, "settings": settings_digest}: fail("%s piece %d: its Opus floor's manifest is not §7.9's" % (cid, k)) elif base_cap == "wai.audio.score": ch = contract["channels"] pcm = mix[s * ch:(s + n) * ch] digest = sha256(s16le(pcm)) floor_payload = flac(pcm, ch, tb[0]) # The piece's own score mixes down to the whole's samples of the piece. try: pc, pn = read_score(base) ok = pc["duration"] == n and mixdown(pc, pn) == pcm and base == write_score(base) and \ score_contract(base) == canonical_contract(pc) except Exception: ok = False if not ok: fail("%s piece %d: its score does not mix down to the source's samples" % (cid, k)) elif base_cap == "wai.graphics.vector": digest = sha256(b"".join(WVC.frame_digest(doc, z.w, z.h, tb[0], tb[1], g) for g in range(s, s + n))) # The piece's own document: its window the piece's ticks, its frames the # source's (graphics-vector §3.11, P7). try: pd = WVC.load(base) ppf = WVC.ticks_per_frame(pd, tb[0], tb[1]) ok = (pd.H["t0"], pd.H["dur"]) == (s * ppf, n * ppf) and \ sha256(b"".join(WVC.frame_digest(pd, z.w, z.h, tb[0], tb[1], g) for g in range(s, s + n))) == digest except Exception: ok = False if not ok: fail("%s piece %d: its document is not the source's for the piece" % (cid, k)) continue # §6.1: the piece is the source's window slice, byte for byte; §6.2: it # has the source's document digest. # (One check: a piece is its source's window slice exactly when it has the # piece's window, which is checked above, and its source's document digest.) if "document" not in skip and (WVC.document_digest(pd) != WVC.document_digest(doc) or base != WVC.window_slice(doc, s * ppf, n * ppf)): fail("%s piece %d: not the window slice of its source: another document digest (graphics-vector §6.1, §6.2)" % (cid, k)) cap_pkg[cid].append(WVC.captions(pd)) if floor_cap == "wai.text.zstd" and "floor" not in skip: # §6.3: the floor is the piece's transcript in the raw frame, under # the manifest that presents the piece's base. floor_payload = WVC.text_floor(pd) fm = manifest_of(objs[p["first"] + 1]) if len(es) > 1 else {} settings_digest = B3.blake3(b"wai:render-settings\x01" + b'{"source":"encode"}').hex() if fm.get("media") != "text" or fm.get("target") != {"bytes": len(WVC.transcript_json(pd)), "tb": pd.H["tb"]} or \ fm.get("derived_from") != {"motif": es[0]["hash"].hex(), "motif_capability": "wai.graphics.vector", "renderer": WVC.FLOOR_RENDERER, "settings": settings_digest}: fail("%s piece %d: its text floor's manifest is not graphics-vector §6.3's" % (cid, k)) if len(es) > 1 and WVC.zstd_raw_read(payload_of(objs[p["first"] + 1])) != WVC.transcript_json(pd): fail("%s piece %d: its text floor does not read back to its transcript" % (cid, k)) elif base_cap == "wai.text.timed": seg = segment(cues, s, s + n).encode() digest = sha256(seg) want_payload = seg try: tracks_pkg[-1][1].extend(segment_cues(base.decode())) except Exception: fail("%s piece %d: its segment does not read" % (cid, k)) # Its manifest's target: the component's language and the piece's span. if manifest_of(objs[p["first"]]).get("target") != {"lang": c["lang"], "ms": n}: fail("%s piece %d: its target is not the piece's" % (cid, k)) elif base_cap == "wai.feed.state": digest = bytes(32) # The seal: its final tick the piece's last, signed by the receipt's key. nsec = le(base, 4, 2) secs = {} for i in range(nsec): kind, off, ln = base[6 + 9 * i], le(base, 7 + 9 * i, 4), le(base, 11 + 9 * i, 4) secs[kind] = base[6 + 9 * nsec + off:6 + 9 * nsec + off + ln] seal = secs.get(5, b"") pre = b"wai:world-seal\x01" + B3.blake3(secs[1]) + B3.blake3(secs[2]) + B3.blake3(secs.get(4, b"")) + seal[:40] if len(seal) != 104 or le(seal, 0, 8) != s + n - 1 or not ED.verifies(bytes.fromhex(receipt["signer_pubkey"]), pre, seal[40:]): fail("%s piece %d: its seal" % (cid, k)) else: fail("%s: a capability this reference does not know: %s" % (cid, base_cap)) continue if es[0]["digest"] != digest: fail("%s piece %d: its prefix_digest is not the source's" % (cid, k)) if want_payload is not None and base != want_payload: fail("%s piece %d: its payload is not §5.8's of the source" % (cid, k)) if floor_payload is not None and (len(es) < 2 or payload_of(objs[p["first"] + 1]) != floor_payload): fail("%s piece %d: its floor is not %s" % (cid, k, "§7.9's Ogg Opus of the floor's packets" if opus else "the text floor of its transcript (graphics-vector §6.3)" if floor_cap == "wai.text.zstd" else "the FLAC of its mixdown")) if "captions" not in skip: for cid in sorted(cap_src): why = caption_rule(cap_src[cid], tracks_src) if why: fail("%s: caption_without_track on its sources: %s" % (cid, why)) merged = merge_captions(cap_pkg[cid]) if merged != cap_src[cid]: fail("%s: its pieces' caption intervals, merged, are not its source's (graphics-vector §6.4)" % cid) why = caption_rule(merged, tracks_pkg) if why: fail("%s: caption_without_track in the package: %s" % (cid, why)) def opus_faults(pkg, P): """Copies of `pkg` with one fault each in its Opus floor.""" out = [] for c in P["component"]: floors = [r for r in P.get("ladder", []) if r["component"] == c["id"] and r["role"] == "floor"] if not floors or floors[0]["capability"] != "wai.audio.opus": continue ixb = bytearray(pkg["index-%s.wsix" % c["id"]]) ix = read_index(bytes(ixb)) e1 = ix["entries"][1] env = bytearray(pkg["objects/%s.wai" % e1["hash"].hex()]) env[len(env) - 40] ^= 0x01 h = content_hash(bytes(env)) at = 160 + 32 * len(ix["pieces"]) + 128 ixb[at:at + 32] = h m = dict(pkg) m["objects/%s.wai" % h.hex()] = bytes(env) m["index-%s.wsix" % c["id"]] = bytes(ixb) out.append(("a flipped byte in component %s's first Opus floor object" % c["id"], m)) seg = sorted(k for k in pkg if k.startswith("floor/%s/" % c["id"]) and k.endswith(".m4s"))[0] m = dict(pkg) b = bytearray(m[seg]) b[-10] ^= 0x01 m[seg] = bytes(b) out.append(("a flipped byte in component %s's media segment %s" % (c["id"], seg), m)) m = dict(pkg) lb = m["floor.listing"].decode().splitlines() m["floor.listing"] = ("\n".join(lb[:-1]) + "\n").encode() out.append(("component %s's floor.listing without its last line" % c["id"], m)) return out def renamed(pkg, cid, k, env, digest=None): """A copy of `pkg` with entry `k` of component `cid` pointing at the object `env`, and stating `digest` as its decoded-output digest when one is given.""" ixb = bytearray(pkg["index-%s.wsix" % cid]) ix = read_index(bytes(ixb)) at = 160 + 32 * len(ix["pieces"]) + 128 * k h = content_hash(env) ixb[at:at + 32] = h struct.pack_into("= 2: other = WVC.load(raw.replace(word, word[::-1])) ppf = WVC.ticks_per_frame(src, c["timebase"]["num"], c["timebase"]["den"]) piece = WVC.window_slice(other, p1["start"] * ppf, p1["dur"] * ppf) b1 = pkg["objects/%s.wai" % ix["entries"][p1["first"]]["hash"].hex()] env = envelope(b1, piece) m = renamed(pkg, cid, p1["first"], env) if has_floor: pd = WVC.load(piece) f1 = pkg["objects/%s.wai" % ix["entries"][p1["first"] + 1]["hash"].hex()] m = renamed(m, cid, p1["first"] + 1, envelope(f1, WVC.text_floor(pd), {"bytes": len(WVC.transcript_json(pd)), "tb": pd.H["tb"]}, content_hash(env))) out.append(("%s piece 1 cut from a document with its first string reversed" % cid, m, "document", None)) if not WVC.captions(src): continue # §6.4: a caption's cue a millisecond shorter, in its text component's source and # in the package alike: every segment that holds it is the one §5.2 writes of the # changed source, and its entry states that segment's digest. Only the caption # rule can tell. lang, text, shown = max(WVC.captions(src), key=lambda x: x[2][0][1] - x[2][0][0]) for tid, tc in comps.items(): if tc["media"] != "text" or tc["lang"].lower().encode() != lang: continue was = "--> %s " % ts(shown[0][1]) doc = open(os.path.join(gdir, "sources", tc["source"]), "rb").read().decode() assert doc.count(was) == 1 and text.decode() in doc doc2 = doc.replace(was, "--> %s " % ts(shown[0][1] - 1)) cues = cue_blocks(doc2) tix = read_index(pkg["index-%s.wsix" % tid]) m, hit = pkg, 0 for piece in tix["pieces"]: e = tix["entries"][piece["first"]] env = m["objects/%s.wai" % e["hash"].hex()] seg2 = segment(cues, piece["start"], piece["start"] + piece["dur"]).encode() if seg2 != payload_of(env): m = renamed(m, tid, piece["first"], envelope(env, seg2), sha256(seg2)) hit += 1 out.append(("%s's cue of %r a millisecond shorter, in its source and in %d segments" % (tid, text.decode(), hit), m, "captions", {tc["source"]: doc2.encode()})) return out def read_tree(d): out = {} for root, _, files in os.walk(d): for f in files: p = os.path.join(root, f) out[os.path.relpath(p, d).replace(os.sep, "/")] = open(p, "rb").read() return out def main(argv): if len(argv) != 2: print(__doc__) return 2 corpus = argv[1] bad = 0 for name in GOLDENS: gdir = os.path.join(corpus, "multi", name) pkg = read_tree(os.path.join(gdir, "package")) errs = [] check_golden(gdir, pkg, errs.append) for e in errs: print("FAIL %s: %s" % (name, e)) bad += len(errs) # Planted faults: in each component beside the lead, the first base's object with # one payload byte flipped and its entry renamed to it, which every check above # that reads the object must find. P = tomllib.load(open(os.path.join(gdir, "policy.toml"), "rb")) for c in P["component"]: if c["id"] == P["lead"]: continue ixb = bytearray(pkg["index-%s.wsix" % c["id"]]) ix = read_index(bytes(ixb)) e0 = ix["entries"][0] env = bytearray(pkg["objects/%s.wai" % e0["hash"].hex()]) env[len(env) - len(payload_of(bytes(env))) // 2 - 1] ^= 0x20 h = content_hash(bytes(env)) at = 160 + 32 * len(ix["pieces"]) ixb[at:at + 32] = h m = dict(pkg) m["objects/%s.wai" % h.hex()] = bytes(env) m["index-%s.wsix" % c["id"]] = bytes(ixb) found = [] check_golden(gdir, m, found.append) if not found: print("FAIL %s: a flipped payload byte in component %s is not found" % (name, c["id"])) bad += 1 else: print("ok %s: a flipped payload byte in component %s: %s" % (name, c["id"], found[0])) # An Opus floor's own faults (§7.9): its first floor object with a payload byte # flipped, and a media segment with a byte flipped under its old name. if os.path.isdir(os.path.join(gdir, "floor")): for what, edit in opus_faults(pkg, P): found = [] try: check_golden(gdir, edit, found.append) except Exception as x: # a refusal the reader raises is a fault found found.append(repr(x)) if not found: print("FAIL %s: %s is not found" % (name, what)) bad += 1 else: print("ok %s: %s: %s" % (name, what, found[0])) # Graphics-vector §6: each fault is found by its own check, and by no other: with # that check left out the faulted package is taken, so a verifier without the # check is caught by this fault. for what, edit, check, srcs in section6_faults(gdir, pkg, P): found, weak = [], [] check_golden(gdir, edit, found.append, sources=srcs) check_golden(gdir, edit, weak.append, skip=(check,), sources=srcs) if not found: print("FAIL %s: %s is not found" % (name, what)) bad += 1 elif weak: print("FAIL %s: %s is found by another check too: %s" % (name, what, weak[0])) bad += 1 else: print("ok %s: %s: %s; taken with the %s check left out" % (name, what, found[0], check)) if not errs: print("ok %s: every component's digests and objects recomputed from its sources" % name) return 1 if bad else 0 if __name__ == "__main__": sys.exit(main(sys.argv))