@blockcast/mmt-manifest-verify 0.3.0 → 0.4.0-main.1d3ea1cc8ff2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,123 @@
1
+ import { type BcProvenanceV2Endpoint } from './bc-provenance-v2.js';
2
+ /**
3
+ * Receiver enforcement for bc-provenance version 2, draft-ramadan-moq-multicast-01
4
+ * Section 7.2.7 at abf183bfb83e616909453872c4d788db4b3acd19 (md :1397-2010).
5
+ * One instance is one flow (S, G, port) of one stream generation.
6
+ */
7
+ /** Record path: `manifestPort` on the multicast tuple, or the MoQ manifest track mirror. */
8
+ export type BcpV2RecordPath = 'multicast' | 'mirror';
9
+ /** Data path: the multicast group, or a MoQ unicast path (hold queue widened by W). */
10
+ export type BcpV2DataPath = 'multicast' | 'unicast';
11
+ export type BcpV2RecordDrop = 'length' | 'magic' | 'kid' | 'epoch' | 'mseq' | 'closed' | 'sent' | 'count' | 'hash_alg' | 'ctx' | 'budget' | 'signature' | 'duplicate';
12
+ export interface BcpV2Key {
13
+ kid: number;
14
+ publicKey: Uint8Array;
15
+ firstEpoch: number;
16
+ }
17
+ export interface BcpV2ReceiverConfig {
18
+ endpoint: BcProvenanceV2Endpoint;
19
+ keys: readonly BcpV2Key[];
20
+ /** Catalog (or provisioned) join floor. */
21
+ minEpoch: number;
22
+ /** Per-kid epoch floor kept with a key pin; applies at join. */
23
+ pinnedEpochFloor?: ReadonlyMap<number, number>;
24
+ /** Endpoint `bandwidth`, bits per second; bounds the hold queues. */
25
+ bandwidth: number;
26
+ maxAuthDelayMs?: number;
27
+ manifestTimerMs?: number;
28
+ /** Recomputed `ctx`; omit when the receiver has no catalog (ctx carried blind). */
29
+ catalogCtx?: Uint8Array;
30
+ acceptedHashAlgs?: readonly number[];
31
+ /** Widening W (ms) of the unicast hold and the mirror's freshness; capped at 5000. */
32
+ widenMs?: number;
33
+ /** True when the receiver reads the manifest track and may be on the multicast path: the lead applies. */
34
+ applyLead?: boolean;
35
+ /** False on a receiver without a UTC-synchronized clock (Clock paragraph). */
36
+ checkFreshness?: boolean;
37
+ /** Unix milliseconds; one clock serves both the UTC freshness check and the timers. */
38
+ now?: () => number;
39
+ verifySignature?: (publicKey: Uint8Array, message: Uint8Array, signature: Uint8Array) => boolean;
40
+ }
41
+ export interface BcpV2RecordResult {
42
+ verdict: 'verified' | BcpV2RecordDrop;
43
+ /** Held datagrams admitted, in order: by a verified record, or by a duplicate copy that raised the lead. */
44
+ admitted: Uint8Array[];
45
+ }
46
+ export interface BcpV2DatagramResult {
47
+ verdict: 'admitted' | 'held' | 'duplicate' | 'overflow';
48
+ admitted: Uint8Array[];
49
+ }
50
+ /** The bound of Section 7.2.5 (Emission and Cadence) on the lead and on W. */
51
+ export declare const BCPV2_LEAD_BOUND_MS = 5000;
52
+ interface Bucket {
53
+ tokens: number;
54
+ last: number;
55
+ dropped: number;
56
+ }
57
+ export declare class BcProvenanceV2Receiver {
58
+ readonly maxAuthDelayMs: number;
59
+ readonly manifestTimerMs: number;
60
+ readonly widenMs: number;
61
+ /** Datagrams that left a hold queue at expiry, per path: the loss signal for failover. */
62
+ readonly expired: {
63
+ multicast: number;
64
+ unicast: number;
65
+ };
66
+ private readonly cfg;
67
+ private readonly now;
68
+ private readonly verifySig;
69
+ private readonly accepted;
70
+ private readonly queueLimit;
71
+ private current;
72
+ private previous;
73
+ private graceStart;
74
+ private hashAlg;
75
+ private verified;
76
+ private highest;
77
+ private closedAt;
78
+ private lead;
79
+ private pending;
80
+ private admittedUntil;
81
+ private hold;
82
+ private holdBytes;
83
+ private order;
84
+ readonly buckets: Record<BcpV2RecordPath, Bucket>;
85
+ constructor(cfg: BcpV2ReceiverConfig);
86
+ private get grace();
87
+ /** The mirror's lead in force: 0 without a manifest track, the bound until one is measured. */
88
+ get leadMs(): number;
89
+ /** Step 1: a record datagram on `manifestPort`, or a record object of the manifest track. */
90
+ onRecord(bytes: Uint8Array, path: BcpV2RecordPath): BcpV2RecordResult;
91
+ /** Step 2: a data datagram on `port` (or a packet of a listed track over MoQ unicast). */
92
+ onDatagram(datagram: Uint8Array, path: BcpV2DataPath): BcpV2DatagramResult;
93
+ /**
94
+ * Discard the per-flow state on a `streamId` change or a key-set change that fails the
95
+ * flow's current (kid, epoch): budgets and hold queues survive, held digests are cleared.
96
+ */
97
+ resetGeneration(): void;
98
+ /** The receiver ceased to hold the endpoint: drop everything; no drop here is an expiry. */
99
+ release(): void;
100
+ private digest;
101
+ private enqueue;
102
+ /** Remove and return the oldest held datagram with `digest`, across both queues. */
103
+ private takeHeld;
104
+ private dropAdmittedHeld;
105
+ /** Step 1 pair handling: admit a held copy, or insert a pending entry. */
106
+ private handlePair;
107
+ /** A byte-identical copy dropped by the already-verified lookup. */
108
+ private arrival;
109
+ private previousAdmitted;
110
+ /** The replay floor this record meets: its path's, or the higher of both from the mirror. */
111
+ private floor;
112
+ private raise;
113
+ private take;
114
+ private expire;
115
+ /**
116
+ * Retire verified entries below their arrival path's replay floor, keeping a mirrored entry
117
+ * while the freshness check would still pass its copy on `manifestPort`.
118
+ * ponytail: linear scan per record; index by (kid, epoch) if retained sets grow past a few thousand.
119
+ */
120
+ private prune;
121
+ }
122
+ export {};
123
+ //# sourceMappingURL=bc-provenance-v2-receiver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bc-provenance-v2-receiver.d.ts","sourceRoot":"","sources":["../src/bc-provenance-v2-receiver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,409 @@
1
+ import { ed25519 } from '@noble/curves/ed25519';
2
+ import { sha256 } from '@noble/hashes/sha256';
3
+ import { BCPV2_HASH_ALG_SHA256, BCPV2_MAX_RECORD_LENGTH, BCPV2_MIN_RECORD_LENGTH, bcProvenanceV2DatagramDigest, bcProvenanceV2SignedMessage, decodeBcProvenanceV2Record, } from './bc-provenance-v2.js';
4
+ /** The bound of Section 7.2.5 (Emission and Cadence) on the lead and on W. */
5
+ export const BCPV2_LEAD_BOUND_MS = 5000;
6
+ const REPLAY_WINDOW = 64n;
7
+ const BUCKET_DEPTH = 64;
8
+ const BUCKET_RATE_PER_MS = 1;
9
+ const hex = (bytes) => Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
10
+ function sameBytes(a, b) {
11
+ if (a.byteLength !== b.byteLength)
12
+ return false;
13
+ let diff = 0;
14
+ for (let i = 0; i < a.byteLength; i++)
15
+ diff |= a[i] ^ b[i];
16
+ return diff === 0;
17
+ }
18
+ export class BcProvenanceV2Receiver {
19
+ maxAuthDelayMs;
20
+ manifestTimerMs;
21
+ widenMs;
22
+ /** Datagrams that left a hold queue at expiry, per path: the loss signal for failover. */
23
+ expired = { multicast: 0, unicast: 0 };
24
+ cfg;
25
+ now;
26
+ verifySig;
27
+ accepted;
28
+ queueLimit;
29
+ current = null;
30
+ previous = null;
31
+ graceStart = {};
32
+ hashAlg = null;
33
+ verified = new Map();
34
+ highest = { multicast: new Map(), mirror: new Map() };
35
+ closedAt = new Map();
36
+ lead = null;
37
+ pending = new Map();
38
+ admittedUntil = new Map();
39
+ hold = { multicast: [], unicast: [] };
40
+ holdBytes = { multicast: 0, unicast: 0 };
41
+ order = 0;
42
+ buckets;
43
+ constructor(cfg) {
44
+ this.maxAuthDelayMs = cfg.maxAuthDelayMs ?? 200;
45
+ this.manifestTimerMs = cfg.manifestTimerMs ?? 20;
46
+ // Section 4.1 / 7.2.6: an endpoint outside these ranges is ignored, never clamped.
47
+ if (!(this.maxAuthDelayMs >= 50 && this.maxAuthDelayMs <= 1000) || !(this.manifestTimerMs >= 1)) {
48
+ throw new Error('BCPV2 endpoint ignored: maxAuthDelayMs or manifestTimerMs out of range');
49
+ }
50
+ if (!(cfg.bandwidth > 0))
51
+ throw new Error('BCPV2 endpoint ignored: protected endpoint without bandwidth');
52
+ const kids = new Set(cfg.keys.map((k) => k.kid));
53
+ const firsts = new Set(cfg.keys.map((k) => k.firstEpoch));
54
+ if (cfg.keys.length < 1 || kids.size !== cfg.keys.length || firsts.size !== cfg.keys.length) {
55
+ throw new Error('BCPV2 key set invalid: no keys, or a repeated kid or firstEpoch');
56
+ }
57
+ this.cfg = cfg;
58
+ this.widenMs = Math.min(Math.max(cfg.widenMs ?? 0, 0), BCPV2_LEAD_BOUND_MS);
59
+ this.now = cfg.now ?? Date.now;
60
+ this.verifySig = cfg.verifySignature ?? ((pk, msg, sig) => {
61
+ try {
62
+ return ed25519.verify(sig, msg, pk, { zip215: false });
63
+ }
64
+ catch {
65
+ return false;
66
+ }
67
+ });
68
+ this.accepted = cfg.acceptedHashAlgs ?? [BCPV2_HASH_ALG_SHA256];
69
+ // Receiver-local policy (Section 7.3) bounds the catalog's bandwidth: 10 Gbit/s.
70
+ const bandwidth = Math.min(cfg.bandwidth, 10e9);
71
+ this.queueLimit = {
72
+ multicast: (this.maxAuthDelayMs * bandwidth) / 8000,
73
+ unicast: ((this.maxAuthDelayMs + this.widenMs) * bandwidth) / 8000,
74
+ };
75
+ const t = this.now();
76
+ this.buckets = {
77
+ multicast: { tokens: BUCKET_DEPTH, last: t, dropped: 0 },
78
+ mirror: { tokens: BUCKET_DEPTH, last: t, dropped: 0 },
79
+ };
80
+ }
81
+ get grace() {
82
+ return this.maxAuthDelayMs + 2 * this.manifestTimerMs;
83
+ }
84
+ /** The mirror's lead in force: 0 without a manifest track, the bound until one is measured. */
85
+ get leadMs() {
86
+ if (!this.cfg.applyLead)
87
+ return 0;
88
+ return this.lead ?? BCPV2_LEAD_BOUND_MS;
89
+ }
90
+ /** Step 1: a record datagram on `manifestPort`, or a record object of the manifest track. */
91
+ onRecord(bytes, path) {
92
+ const now = this.now();
93
+ this.expire(now);
94
+ const drop = (verdict) => ({ verdict, admitted: [] });
95
+ const len = bytes.byteLength;
96
+ if (len < BCPV2_MIN_RECORD_LENGTH || len > BCPV2_MAX_RECORD_LENGTH || (len - 132) % 32 !== 0)
97
+ return drop('length');
98
+ const view = new DataView(bytes.buffer, bytes.byteOffset, len);
99
+ if (view.getUint32(0) !== 0x4d484d32)
100
+ return drop('magic');
101
+ const kid = view.getUint32(4);
102
+ const epoch = view.getUint32(8);
103
+ const mseq = view.getBigUint64(12);
104
+ const count = view.getUint16(28);
105
+ const hashAlg = bytes[30];
106
+ const sent = view.getUint32(32);
107
+ const key = this.cfg.keys.find((k) => k.kid === kid);
108
+ if (!key)
109
+ return drop('kid');
110
+ const next = Math.min(...this.cfg.keys.map((k) => k.firstEpoch).filter((f) => f > key.firstEpoch), Infinity);
111
+ if (epoch < key.firstEpoch || epoch >= next)
112
+ return drop('epoch');
113
+ const id = `${kid}:${epoch}:${mseq}`;
114
+ const seen = this.verified.get(id);
115
+ if (seen) {
116
+ // One lookup and one hash: a byte-identical copy counts as an arrival on this path.
117
+ const admitted = hex(sha256(bytes)) === seen.digest ? this.arrival(seen, path, now) : [];
118
+ return { verdict: 'duplicate', admitted };
119
+ }
120
+ const ke = `${kid}:${epoch}`;
121
+ if (this.current === null) {
122
+ if (epoch < this.cfg.minEpoch || epoch < (this.cfg.pinnedEpochFloor?.get(kid) ?? 0))
123
+ return drop('epoch');
124
+ }
125
+ else if (epoch < this.current.epoch && !this.previousAdmitted(epoch, path, now)) {
126
+ return drop('epoch');
127
+ }
128
+ const floor = this.floor(ke, path);
129
+ if (floor !== undefined && mseq <= floor - REPLAY_WINDOW)
130
+ return drop('mseq');
131
+ const closed = this.closedAt.get(ke);
132
+ if (closed !== undefined && mseq > closed)
133
+ return drop('closed');
134
+ if (this.cfg.checkFreshness !== false) {
135
+ const behind = 7000 + this.maxAuthDelayMs + (path === 'mirror' ? this.widenMs : 0);
136
+ if (sent * 1000 < now - behind || sent * 1000 > now + 6000)
137
+ return drop('sent');
138
+ }
139
+ if (count !== (len - 132) / 32)
140
+ return drop('count');
141
+ if (!this.accepted.includes(hashAlg) || (this.hashAlg !== null && hashAlg !== this.hashAlg))
142
+ return drop('hash_alg');
143
+ if (this.cfg.catalogCtx && !sameBytes(bytes.subarray(36, 68), this.cfg.catalogCtx))
144
+ return drop('ctx');
145
+ if (!this.take(path, now))
146
+ return drop('budget');
147
+ const record = decodeBcProvenanceV2Record(bytes);
148
+ if (!this.verifySig(key.publicKey, bcProvenanceV2SignedMessage(record, this.cfg.endpoint), record.signature)) {
149
+ return drop('signature');
150
+ }
151
+ if (this.current === null || epoch > this.current.epoch) {
152
+ if (this.current !== null) {
153
+ this.previous = { epoch: this.current.epoch, deadline: now + BCPV2_LEAD_BOUND_MS + this.grace };
154
+ }
155
+ this.current = { epoch, since: now };
156
+ this.graceStart = { [path]: now };
157
+ if (this.hashAlg === null) {
158
+ this.hashAlg = hashAlg;
159
+ for (const queue of Object.values(this.hold)) {
160
+ for (const held of queue)
161
+ held.digest ??= this.digest(held.datagram);
162
+ }
163
+ }
164
+ }
165
+ else if (epoch === this.current.epoch) {
166
+ this.graceStart[path] ??= now;
167
+ }
168
+ const entry = {
169
+ kid, epoch, mseq, path, arrival: now, sent,
170
+ digest: hex(sha256(bytes)),
171
+ pairs: record.digests.map((d, i) => ({ digest: hex(d), seq: record.firstSeq + BigInt(i), admitted: false })),
172
+ awaitingMulticast: path === 'mirror',
173
+ };
174
+ this.verified.set(id, entry);
175
+ this.raise(ke, path, mseq);
176
+ if (record.flags & 1)
177
+ this.closedAt.set(ke, mseq);
178
+ const widen = path === 'mirror' ? (this.cfg.applyLead ? this.leadMs : this.widenMs) : 0;
179
+ const admitted = [];
180
+ for (const pair of entry.pairs)
181
+ this.handlePair(pair, now, now + this.grace + widen, now, admitted);
182
+ this.dropAdmittedHeld();
183
+ this.prune(now);
184
+ return { verdict: 'verified', admitted };
185
+ }
186
+ /** Step 2: a data datagram on `port` (or a packet of a listed track over MoQ unicast). */
187
+ onDatagram(datagram, path) {
188
+ const now = this.now();
189
+ this.expire(now);
190
+ if (this.hashAlg !== null) {
191
+ const d = this.digest(datagram);
192
+ const list = this.pending.get(d);
193
+ if (list?.length) {
194
+ list.sort((a, b) => (a.pair.seq < b.pair.seq ? -1 : a.pair.seq > b.pair.seq ? 1 : 0));
195
+ const hit = list.shift();
196
+ if (list.length === 0)
197
+ this.pending.delete(d);
198
+ hit.pair.pending = undefined;
199
+ hit.pair.admitted = true;
200
+ this.admittedUntil.set(d, now + this.maxAuthDelayMs + this.leadMs);
201
+ return { verdict: 'admitted', admitted: [datagram] };
202
+ }
203
+ if (this.admittedUntil.has(d))
204
+ return { verdict: 'duplicate', admitted: [] };
205
+ return this.enqueue({ digest: d, datagram, expiry: 0, order: 0 }, path, now);
206
+ }
207
+ return this.enqueue({ datagram, expiry: 0, order: 0 }, path, now);
208
+ }
209
+ /**
210
+ * Discard the per-flow state on a `streamId` change or a key-set change that fails the
211
+ * flow's current (kid, epoch): budgets and hold queues survive, held digests are cleared.
212
+ */
213
+ resetGeneration() {
214
+ this.current = null;
215
+ this.previous = null;
216
+ this.graceStart = {};
217
+ this.hashAlg = null;
218
+ this.verified.clear();
219
+ this.highest = { multicast: new Map(), mirror: new Map() };
220
+ this.closedAt.clear();
221
+ this.lead = null;
222
+ this.pending.clear();
223
+ this.admittedUntil.clear();
224
+ for (const queue of Object.values(this.hold))
225
+ for (const held of queue)
226
+ held.digest = undefined;
227
+ }
228
+ /** The receiver ceased to hold the endpoint: drop everything; no drop here is an expiry. */
229
+ release() {
230
+ this.resetGeneration();
231
+ this.hold = { multicast: [], unicast: [] };
232
+ this.holdBytes = { multicast: 0, unicast: 0 };
233
+ }
234
+ digest(datagram) {
235
+ return hex(bcProvenanceV2DatagramDigest(this.cfg.endpoint, datagram));
236
+ }
237
+ enqueue(held, path, now) {
238
+ if (this.holdBytes[path] + held.datagram.byteLength > this.queueLimit[path]) {
239
+ return { verdict: 'overflow', admitted: [] }; // drop newest
240
+ }
241
+ held.expiry = now + this.maxAuthDelayMs + (path === 'unicast' ? this.widenMs : 0);
242
+ held.order = this.order++;
243
+ this.hold[path].push(held);
244
+ this.holdBytes[path] += held.datagram.byteLength;
245
+ return { verdict: 'held', admitted: [] };
246
+ }
247
+ /** Remove and return the oldest held datagram with `digest`, across both queues. */
248
+ takeHeld(digest) {
249
+ let best;
250
+ for (const path of ['multicast', 'unicast']) {
251
+ const index = this.hold[path].findIndex((h) => h.digest === digest);
252
+ if (index >= 0 && (!best || this.hold[path][index].order < best.order)) {
253
+ best = { path, index, order: this.hold[path][index].order };
254
+ }
255
+ }
256
+ if (!best)
257
+ return undefined;
258
+ const [held] = this.hold[best.path].splice(best.index, 1);
259
+ this.holdBytes[best.path] -= held.datagram.byteLength;
260
+ return held.datagram;
261
+ }
262
+ dropAdmittedHeld() {
263
+ for (const path of ['multicast', 'unicast']) {
264
+ this.hold[path] = this.hold[path].filter((h) => {
265
+ const keep = h.digest === undefined || !this.admittedUntil.has(h.digest);
266
+ if (!keep)
267
+ this.holdBytes[path] -= h.datagram.byteLength;
268
+ return keep;
269
+ });
270
+ }
271
+ }
272
+ /** Step 1 pair handling: admit a held copy, or insert a pending entry. */
273
+ handlePair(pair, now, expiry, inserted, out) {
274
+ const datagram = this.takeHeld(pair.digest);
275
+ if (datagram) {
276
+ pair.admitted = true;
277
+ this.admittedUntil.set(pair.digest, now + this.maxAuthDelayMs + this.leadMs);
278
+ out.push(datagram);
279
+ return;
280
+ }
281
+ const entry = { pair, inserted, expiry };
282
+ pair.pending = entry;
283
+ const list = this.pending.get(pair.digest);
284
+ if (list)
285
+ list.push(entry);
286
+ else
287
+ this.pending.set(pair.digest, [entry]);
288
+ }
289
+ /** A byte-identical copy dropped by the already-verified lookup. */
290
+ arrival(seen, path, now) {
291
+ const ke = `${seen.kid}:${seen.epoch}`;
292
+ this.raise(ke, path, seen.mseq);
293
+ if (this.current && seen.epoch === this.current.epoch)
294
+ this.graceStart[path] ??= now;
295
+ if (path !== 'multicast' || !seen.awaitingMulticast)
296
+ return [];
297
+ seen.awaitingMulticast = false;
298
+ if (!this.cfg.applyLead)
299
+ return [];
300
+ const t = this.manifestTimerMs;
301
+ const interval = Math.min(Math.ceil((now - seen.arrival) / t) * t, BCPV2_LEAD_BOUND_MS);
302
+ if (this.lead === null) {
303
+ this.lead = interval; // the bound applied until now covered every earlier entry
304
+ return [];
305
+ }
306
+ if (interval <= this.lead)
307
+ return [];
308
+ this.lead = interval;
309
+ // Re-handle this record and every mirrored record within the raised lead still awaiting its copy.
310
+ const out = [];
311
+ const records = [seen, ...[...this.verified.values()].filter((v) => v.awaitingMulticast && v.arrival >= now - interval)];
312
+ for (const v of records) {
313
+ for (const pair of v.pairs) {
314
+ if (pair.admitted) {
315
+ this.admittedUntil.set(pair.digest, now + this.maxAuthDelayMs + interval);
316
+ }
317
+ else if (pair.pending) {
318
+ pair.pending.expiry = pair.pending.inserted + this.grace + interval;
319
+ }
320
+ else {
321
+ this.handlePair(pair, now, now + this.grace + interval, now, out);
322
+ }
323
+ }
324
+ }
325
+ this.dropAdmittedHeld();
326
+ return out;
327
+ }
328
+ previousAdmitted(epoch, path, now) {
329
+ if (!this.previous || epoch !== this.previous.epoch)
330
+ return false; // expire() retires it at its deadline
331
+ const m = this.graceStart.multicast;
332
+ if (path === 'multicast')
333
+ return m === undefined || now <= m + this.grace;
334
+ const starts = [m, this.graceStart.mirror].filter((s) => s !== undefined);
335
+ return starts.length > 0 && now <= Math.min(...starts) + this.grace;
336
+ }
337
+ /** The replay floor this record meets: its path's, or the higher of both from the mirror. */
338
+ floor(ke, path) {
339
+ const m = this.highest.multicast.get(ke);
340
+ if (path === 'multicast')
341
+ return m;
342
+ const r = this.highest.mirror.get(ke);
343
+ if (m === undefined)
344
+ return r;
345
+ return r === undefined || m > r ? m : r;
346
+ }
347
+ raise(ke, path, mseq) {
348
+ const h = this.highest[path].get(ke);
349
+ if (h === undefined || mseq > h)
350
+ this.highest[path].set(ke, mseq);
351
+ }
352
+ take(path, now) {
353
+ const b = this.buckets[path];
354
+ b.tokens = Math.min(BUCKET_DEPTH, b.tokens + (now - b.last) * BUCKET_RATE_PER_MS);
355
+ b.last = now;
356
+ if (b.tokens < 1) {
357
+ b.dropped++;
358
+ return false;
359
+ }
360
+ b.tokens -= 1;
361
+ return true;
362
+ }
363
+ expire(now) {
364
+ for (const path of ['multicast', 'unicast']) {
365
+ this.hold[path] = this.hold[path].filter((h) => {
366
+ if (h.expiry > now)
367
+ return true;
368
+ this.holdBytes[path] -= h.datagram.byteLength;
369
+ this.expired[path]++;
370
+ return false;
371
+ });
372
+ }
373
+ for (const [d, list] of this.pending) {
374
+ const live = list.filter((p) => {
375
+ if (p.expiry > now)
376
+ return true;
377
+ p.pair.pending = undefined;
378
+ return false;
379
+ });
380
+ if (live.length)
381
+ this.pending.set(d, live);
382
+ else
383
+ this.pending.delete(d);
384
+ }
385
+ for (const [d, until] of this.admittedUntil)
386
+ if (until <= now)
387
+ this.admittedUntil.delete(d);
388
+ if (this.previous && now > this.previous.deadline)
389
+ this.previous = null;
390
+ }
391
+ /**
392
+ * Retire verified entries below their arrival path's replay floor, keeping a mirrored entry
393
+ * while the freshness check would still pass its copy on `manifestPort`.
394
+ * ponytail: linear scan per record; index by (kid, epoch) if retained sets grow past a few thousand.
395
+ */
396
+ prune(now) {
397
+ const retention = 7000 + this.maxAuthDelayMs;
398
+ for (const [id, v] of this.verified) {
399
+ const h = this.highest[v.path].get(`${v.kid}:${v.epoch}`);
400
+ const aboveFloor = h === undefined || v.mseq > h - REPLAY_WINDOW;
401
+ const fresh = this.cfg.checkFreshness === false ? v.arrival + retention >= now : v.sent * 1000 + retention >= now;
402
+ const current = this.current && (v.epoch === this.current.epoch || v.epoch === this.previous?.epoch);
403
+ if (current && (aboveFloor || (v.path === 'mirror' && fresh)))
404
+ continue;
405
+ this.verified.delete(id);
406
+ }
407
+ }
408
+ }
409
+ //# sourceMappingURL=bc-provenance-v2-receiver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bc-provenance-v2-receiver.js","sourceRoot":"","sources":["../src/bc-provenance-v2-receiver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ /** Fixed-width bytes before a record's digest list. */
2
+ export declare const BCPV2_HEADER_LENGTH = 68;
3
+ export declare const BCPV2_SIGNATURE_LENGTH = 64;
4
+ export declare const BCPV2_MIN_RECORD_LENGTH: number;
5
+ export declare const BCPV2_MAX_RECORD_LENGTH = 1316;
6
+ export declare const BCPV2_MAX_DIGESTS = 37;
7
+ export declare const BCPV2_HASH_ALG_SHA256 = 1;
8
+ export interface BcProvenanceV2Endpoint {
9
+ /** S in the AMBI pseudoheader and signature context. */
10
+ sourceAddress: string;
11
+ /** G in the AMBI pseudoheader and signature context. */
12
+ groupAddress: string;
13
+ /** UDP source and destination port of protected datagrams. */
14
+ port: number;
15
+ /** UDP destination port carrying manifest records. */
16
+ manifestPort: number;
17
+ /** Catalog-declared channel generation. */
18
+ streamId: number;
19
+ }
20
+ export interface BcProvenanceV2Record {
21
+ kid: number;
22
+ epoch: number;
23
+ mseq: bigint;
24
+ firstSeq: bigint;
25
+ count: number;
26
+ hashAlg: number;
27
+ flags: number;
28
+ sent: number;
29
+ ctx: Uint8Array;
30
+ digests: Uint8Array[];
31
+ signature: Uint8Array;
32
+ /** Record bytes covered by the signature, excluding the signature itself. */
33
+ body: Uint8Array;
34
+ /** A defensive copy of the complete wire record. */
35
+ raw: Uint8Array;
36
+ }
37
+ /** Parse an IPv4 or IPv6 address in the native-width form used on the wire. */
38
+ export declare function parseBcProvenanceV2Address(address: string): Uint8Array;
39
+ /**
40
+ * Decode the fixed-layout BCPV2 record from multicast-01 Section 7.2.3.
41
+ * Structural validation happens before callers inspect the variable digest list.
42
+ */
43
+ export declare function decodeBcProvenanceV2Record(input: Uint8Array): BcProvenanceV2Record;
44
+ /** Return the exact Ed25519 preimage from multicast-01 Section 7.2.4. */
45
+ export declare function bcProvenanceV2SignedMessage(record: BcProvenanceV2Record, endpoint: BcProvenanceV2Endpoint): Uint8Array;
46
+ /**
47
+ * Compute the AMBI Section 3.4.2 digest for one transmitted datagram.
48
+ * The payload includes the Source FEC Payload ID when one was transmitted.
49
+ */
50
+ export declare function bcProvenanceV2DatagramDigest(endpoint: BcProvenanceV2Endpoint, payload: Uint8Array): Uint8Array;
51
+ /** Verify the ordered digest list against the transmitted datagrams. */
52
+ export declare function verifyBcProvenanceV2Datagrams(record: BcProvenanceV2Record, endpoint: BcProvenanceV2Endpoint, datagrams: readonly Uint8Array[]): boolean;
53
+ export interface BcProvenanceV2Params {
54
+ codec: string;
55
+ /** 0 where MOQ-MMT Section 4.4.2 resolves none. */
56
+ timescale: number;
57
+ groupDurationTicks: number;
58
+ /** Absent for an entry with no `fec` object. */
59
+ fec?: {
60
+ algorithm: string;
61
+ sourceSymbols: number;
62
+ repairSymbols: number;
63
+ symbolSize: number;
64
+ interleaveDepthMs?: number;
65
+ };
66
+ }
67
+ /** `params_hash` of multicast-01 Section 7.2.4 (md :1068-1110), hash_alg 1. */
68
+ export declare function bcProvenanceV2ParamsHash(params: BcProvenanceV2Params): Uint8Array;
69
+ /**
70
+ * `ctx` of multicast-01 Section 7.2.4: the namespace fields in order, the endpoint's
71
+ * packetIds ascending, and `params_hash`. A flow without a MoQ catalog uses 32 zero octets.
72
+ */
73
+ export declare function bcProvenanceV2Ctx(namespace: readonly (Uint8Array | string)[], packetIds: readonly number[], params: BcProvenanceV2Params): Uint8Array;
74
+ //# sourceMappingURL=bc-provenance-v2.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bc-provenance-v2.d.ts","sourceRoot":"","sources":["../src/bc-provenance-v2.ts"],"names":[],"mappings":"AAEA,uDAAuD;AACvD,eAAO,MAAM,mBAAmB,KAAK,CAAA;AACrC,eAAO,MAAM,sBAAsB,KAAK,CAAA;AACxC,eAAO,MAAM,uBAAuB,QAAoD,CAAA;AACxF,eAAO,MAAM,uBAAuB,OAAO,CAAA;AAC3C,eAAO,MAAM,iBAAiB,KAAK,CAAA;AACnC,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAEtC,MAAM,WAAW,sBAAsB;IACrC,wDAAwD;IACxD,aAAa,EAAE,MAAM,CAAA;IACrB,wDAAwD;IACxD,YAAY,EAAE,MAAM,CAAA;IACpB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAA;IACpB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,UAAU,CAAA;IACf,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,SAAS,EAAE,UAAU,CAAA;IACrB,6EAA6E;IAC7E,IAAI,EAAE,UAAU,CAAA;IAChB,oDAAoD;IACpD,GAAG,EAAE,UAAU,CAAA;CAChB;AAqED,+EAA+E;AAC/E,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAGtE;AAuBD;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,UAAU,GAAG,oBAAoB,CAmClF;AAED,yEAAyE;AACzE,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,oBAAoB,EAC5B,QAAQ,EAAE,sBAAsB,GAC/B,UAAU,CAiBZ;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,sBAAsB,EAChC,OAAO,EAAE,UAAU,GAClB,UAAU,CAsBZ;AAED,wEAAwE;AACxE,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,oBAAoB,EAC5B,QAAQ,EAAE,sBAAsB,EAChC,SAAS,EAAE,SAAS,UAAU,EAAE,GAC/B,OAAO,CAOT;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAA;IACb,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAA;IACjB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,gDAAgD;IAChD,GAAG,CAAC,EAAE;QACJ,SAAS,EAAE,MAAM,CAAA;QACjB,aAAa,EAAE,MAAM,CAAA;QACrB,aAAa,EAAE,MAAM,CAAA;QACrB,UAAU,EAAE,MAAM,CAAA;QAClB,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAC3B,CAAA;CACF;AAkBD,+EAA+E;AAC/E,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,oBAAoB,GAAG,UAAU,CAajF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,SAAS,CAAC,UAAU,GAAG,MAAM,CAAC,EAAE,EAC3C,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,MAAM,EAAE,oBAAoB,GAC3B,UAAU,CAWZ"}