@blockcast/mmt-manifest-verify 0.1.0

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.
File without changes
@@ -0,0 +1,28 @@
1
+ import { type SourceAuthGroupClose, type SourceAuthObjectEntry } from './source-auth.js';
2
+ export type SourceAuthAdmissionState = 'pending-entry' | 'pending-object' | 'provisional' | 'authenticated';
3
+ export interface SourceAuthObjectAdmission {
4
+ groupId: bigint;
5
+ objectId: number;
6
+ recovered: boolean;
7
+ state: Exclude<SourceAuthAdmissionState, 'pending-object'>;
8
+ }
9
+ /**
10
+ * Bounded media/manifest rendezvous for the browser player receive path.
11
+ * Object digest admission is synchronous; only the group-close signature is deferred.
12
+ */
13
+ export declare class SourceAuthAdmission {
14
+ #private;
15
+ constructor(options: {
16
+ manifestAuthenticated: boolean;
17
+ });
18
+ admitObject(input: {
19
+ groupId: bigint;
20
+ objectId: number;
21
+ bytes: Uint8Array;
22
+ recovered?: boolean;
23
+ }): SourceAuthObjectAdmission;
24
+ admitEntry(entry: SourceAuthObjectEntry): SourceAuthObjectAdmission | SourceAuthAdmissionState;
25
+ objectState(objectId: number): SourceAuthAdmissionState | undefined;
26
+ verifyClose(close: SourceAuthGroupClose, authScope: Uint8Array, publicKey: CryptoKey, subtle?: SubtleCrypto): Promise<void>;
27
+ }
28
+ //# sourceMappingURL=admission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admission.d.ts","sourceRoot":"","sources":["../src/admission.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC3B,MAAM,kBAAkB,CAAA;AAEzB,MAAM,MAAM,wBAAwB,GAChC,eAAe,GACf,gBAAgB,GAChB,aAAa,GACb,eAAe,CAAA;AAEnB,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,OAAO,CAAC,wBAAwB,EAAE,gBAAgB,CAAC,CAAA;CAC3D;AAkBD;;;GAGG;AACH,qBAAa,mBAAmB;;gBASlB,OAAO,EAAE;QAAE,qBAAqB,EAAE,OAAO,CAAA;KAAE;IAIvD,WAAW,CAAC,KAAK,EAAE;QACjB,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;QAChB,KAAK,EAAE,UAAU,CAAA;QACjB,SAAS,CAAC,EAAE,OAAO,CAAA;KACpB,GAAG,yBAAyB;IA0B7B,UAAU,CAAC,KAAK,EAAE,qBAAqB,GAAG,yBAAyB,GAAG,wBAAwB;IAmB9F,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,wBAAwB,GAAG,SAAS;IAO7D,WAAW,CACf,KAAK,EAAE,oBAAoB,EAC3B,SAAS,EAAE,UAAU,EACrB,SAAS,EAAE,SAAS,EACpB,MAAM,GAAE,YAAuC,GAC9C,OAAO,CAAC,IAAI,CAAC;CAqDjB"}
@@ -0,0 +1,128 @@
1
+ import { sourceAuthMerkleRoot, sourceAuthObjectDigest, sourceAuthSignaturePreimage, trimRecoveredSourceAuthObject, } from './source-auth.js';
2
+ function requireU64(name, value) {
3
+ if (value < 0n || value > 0xffffffffffffffffn) {
4
+ throw new Error(`${name} must be an unsigned 64-bit integer`);
5
+ }
6
+ }
7
+ function equalBytes(left, right) {
8
+ if (left.byteLength !== right.byteLength)
9
+ return false;
10
+ return left.every((value, index) => value === right[index]);
11
+ }
12
+ /**
13
+ * Bounded media/manifest rendezvous for the browser player receive path.
14
+ * Object digest admission is synchronous; only the group-close signature is deferred.
15
+ */
16
+ export class SourceAuthAdmission {
17
+ #manifestAuthenticated;
18
+ #entries = new Map();
19
+ #pendingObjects = new Map();
20
+ #entriesAwaitingObjects = new Set();
21
+ #admissions = new Map();
22
+ #groupId = null;
23
+ #closed = false;
24
+ constructor(options) {
25
+ this.#manifestAuthenticated = options.manifestAuthenticated;
26
+ }
27
+ admitObject(input) {
28
+ this.#requireGroup(input.groupId);
29
+ if (this.#closed)
30
+ throw new Error('source-auth group is already closed');
31
+ if (this.#admissions.has(input.objectId) || this.#pendingObjects.has(input.objectId)) {
32
+ throw new Error(`duplicate source-auth object ${input.objectId}`);
33
+ }
34
+ const entry = this.#entries.get(input.objectId);
35
+ if (entry) {
36
+ this.#entriesAwaitingObjects.delete(input.objectId);
37
+ return this.#verifyObject(entry, input.bytes, input.recovered ?? false);
38
+ }
39
+ if (this.#pendingObjects.size >= 1) {
40
+ throw new Error('source-auth media exceeds one-object manifest skew');
41
+ }
42
+ this.#pendingObjects.set(input.objectId, {
43
+ bytes: input.bytes,
44
+ recovered: input.recovered ?? false,
45
+ });
46
+ return {
47
+ groupId: input.groupId,
48
+ objectId: input.objectId,
49
+ recovered: input.recovered ?? false,
50
+ state: 'pending-entry',
51
+ };
52
+ }
53
+ admitEntry(entry) {
54
+ this.#requireGroup(entry.groupId);
55
+ if (this.#closed)
56
+ throw new Error('source-auth group is already closed');
57
+ if (this.#entries.has(entry.objectId)) {
58
+ throw new Error(`duplicate source-auth manifest entry ${entry.objectId}`);
59
+ }
60
+ const pending = this.#pendingObjects.get(entry.objectId);
61
+ if (!pending && this.#entriesAwaitingObjects.size >= 1) {
62
+ throw new Error('source-auth manifest exceeds one-object media skew');
63
+ }
64
+ this.#entries.set(entry.objectId, entry);
65
+ if (!pending) {
66
+ this.#entriesAwaitingObjects.add(entry.objectId);
67
+ return 'pending-object';
68
+ }
69
+ this.#pendingObjects.delete(entry.objectId);
70
+ return this.#verifyObject(entry, pending.bytes, pending.recovered);
71
+ }
72
+ objectState(objectId) {
73
+ if (this.#pendingObjects.has(objectId))
74
+ return 'pending-entry';
75
+ if (this.#entriesAwaitingObjects.has(objectId))
76
+ return 'pending-object';
77
+ if (this.#closed && this.#admissions.has(objectId))
78
+ return 'authenticated';
79
+ return this.#admissions.get(objectId)?.state;
80
+ }
81
+ async verifyClose(close, authScope, publicKey, subtle = globalThis.crypto.subtle) {
82
+ this.#requireGroup(close.groupId);
83
+ if (this.#closed)
84
+ throw new Error('source-auth group is already closed');
85
+ if (this.#pendingObjects.size !== 0 || this.#entriesAwaitingObjects.size !== 0) {
86
+ throw new Error('source-auth group closed with unmatched objects or entries');
87
+ }
88
+ if (close.objectCount !== this.#entries.size || this.#admissions.size !== this.#entries.size) {
89
+ throw new Error('source-auth group close object count mismatch');
90
+ }
91
+ const root = sourceAuthMerkleRoot([...this.#entries.values()]);
92
+ if (!equalBytes(root, close.root))
93
+ throw new Error('source-auth group root mismatch');
94
+ const verified = await subtle.verify('Ed25519', publicKey, new Uint8Array(close.signature).buffer, new Uint8Array(sourceAuthSignaturePreimage(authScope, close.groupId, close.objectCount, root)).buffer);
95
+ if (!verified)
96
+ throw new Error('source-auth group close signature failed');
97
+ for (const admission of this.#admissions.values())
98
+ admission.state = 'authenticated';
99
+ this.#closed = true;
100
+ }
101
+ #requireGroup(groupId) {
102
+ requireU64('groupId', groupId);
103
+ if (this.#groupId === null)
104
+ this.#groupId = groupId;
105
+ else if (this.#groupId !== groupId)
106
+ throw new Error('source-auth group identity mismatch');
107
+ }
108
+ #verifyObject(entry, bytes, recovered) {
109
+ const authenticated = recovered
110
+ ? trimRecoveredSourceAuthObject(bytes, entry.trueLength)
111
+ : bytes;
112
+ if (!recovered && bytes.byteLength !== entry.trueLength) {
113
+ throw new Error(`direct source-auth object length mismatch for ${entry.objectId}`);
114
+ }
115
+ if (!equalBytes(sourceAuthObjectDigest(authenticated), entry.digest)) {
116
+ throw new Error(`source-auth object digest mismatch for ${entry.objectId}`);
117
+ }
118
+ const admission = {
119
+ groupId: entry.groupId,
120
+ objectId: entry.objectId,
121
+ recovered,
122
+ state: this.#manifestAuthenticated ? 'authenticated' : 'provisional',
123
+ };
124
+ this.#admissions.set(entry.objectId, admission);
125
+ return admission;
126
+ }
127
+ }
128
+ //# sourceMappingURL=admission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admission.js","sourceRoot":"","sources":["../src/admission.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './source-auth.js';
2
+ export * from './admission.js';
3
+ export * from './verifier.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './source-auth.js';
2
+ export * from './admission.js';
3
+ export * from './verifier.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA"}
@@ -0,0 +1,37 @@
1
+ export declare const SOURCE_AUTH_MANIFEST_VERSION = 1;
2
+ export declare const SOURCE_AUTH_OBJECT_ENTRY_FRAME = 1;
3
+ export declare const SOURCE_AUTH_GROUP_CLOSE_FRAME = 2;
4
+ export declare const SOURCE_AUTH_OBJECT_ENTRY_LENGTH = 52;
5
+ export declare const SOURCE_AUTH_GROUP_CLOSE_LENGTH = 112;
6
+ export declare const SOURCE_AUTH_MAX_OBJECTS_PER_GROUP = 4096;
7
+ export declare const SOURCE_AUTH_MAX_TRUE_LENGTH: number;
8
+ export declare const SOURCE_AUTH_SCOPE_LENGTH = 32;
9
+ export interface SourceAuthObjectEntry {
10
+ kind: 'object';
11
+ groupId: bigint;
12
+ objectId: number;
13
+ trueLength: number;
14
+ digest: Uint8Array;
15
+ }
16
+ export interface SourceAuthGroupClose {
17
+ kind: 'close';
18
+ groupId: bigint;
19
+ objectCount: number;
20
+ root: Uint8Array;
21
+ signature: Uint8Array;
22
+ }
23
+ export type SourceAuthManifestFrame = SourceAuthObjectEntry | SourceAuthGroupClose;
24
+ export declare function sourceAuthObjectDigest(object: Uint8Array): Uint8Array;
25
+ export declare function sourceAuthLeafHash(groupId: bigint, objectId: number, digest: Uint8Array, trueLength: number): Uint8Array;
26
+ export declare function sourceAuthMerkleRoot(entries: readonly {
27
+ groupId: bigint;
28
+ objectId: number;
29
+ digest: Uint8Array;
30
+ trueLength: number;
31
+ }[]): Uint8Array;
32
+ export declare function trimRecoveredSourceAuthObject(recoveredSymbol: Uint8Array, trueLength: number): Uint8Array;
33
+ export declare function encodeSourceAuthObjectEntry(entry: Omit<SourceAuthObjectEntry, 'kind'>): Uint8Array;
34
+ export declare function encodeSourceAuthGroupClose(close: Omit<SourceAuthGroupClose, 'kind'>): Uint8Array;
35
+ export declare function sourceAuthSignaturePreimage(authScope: Uint8Array, groupId: bigint, objectCount: number, root: Uint8Array): Uint8Array;
36
+ export declare function decodeSourceAuthManifestFrame(frame: Uint8Array): SourceAuthManifestFrame;
37
+ //# sourceMappingURL=source-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-auth.d.ts","sourceRoot":"","sources":["../src/source-auth.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,4BAA4B,IAAI,CAAA;AAC7C,eAAO,MAAM,8BAA8B,IAAI,CAAA;AAC/C,eAAO,MAAM,6BAA6B,IAAI,CAAA;AAC9C,eAAO,MAAM,+BAA+B,KAAK,CAAA;AACjD,eAAO,MAAM,8BAA8B,MAAM,CAAA;AACjD,eAAO,MAAM,iCAAiC,OAAO,CAAA;AACrD,eAAO,MAAM,2BAA2B,QAAmB,CAAA;AAC3D,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAI1C,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,QAAQ,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,UAAU,CAAA;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,UAAU,CAAA;IAChB,SAAS,EAAE,UAAU,CAAA;CACtB;AAED,MAAM,MAAM,uBAAuB,GAAG,qBAAqB,GAAG,oBAAoB,CAAA;AA2BlF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAErE;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,GACjB,UAAU,CAYZ;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,SAAS;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,UAAU,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB,EAAE,GACF,UAAU,CA4BZ;AAED,wBAAgB,6BAA6B,CAC3C,eAAe,EAAE,UAAU,EAC3B,UAAU,EAAE,MAAM,GACjB,UAAU,CAMZ;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,GACzC,UAAU,CAcZ;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC,GACxC,UAAU,CAiBZ;AAED,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,UAAU,EACrB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,UAAU,GACf,UAAU,CAgBZ;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,UAAU,GAAG,uBAAuB,CAwCxF"}
@@ -0,0 +1,179 @@
1
+ import { blake3 } from '@noble/hashes/blake3';
2
+ export const SOURCE_AUTH_MANIFEST_VERSION = 1;
3
+ export const SOURCE_AUTH_OBJECT_ENTRY_FRAME = 1;
4
+ export const SOURCE_AUTH_GROUP_CLOSE_FRAME = 2;
5
+ export const SOURCE_AUTH_OBJECT_ENTRY_LENGTH = 52;
6
+ export const SOURCE_AUTH_GROUP_CLOSE_LENGTH = 112;
7
+ export const SOURCE_AUTH_MAX_OBJECTS_PER_GROUP = 4096;
8
+ export const SOURCE_AUTH_MAX_TRUE_LENGTH = 16 * 1024 * 1024;
9
+ export const SOURCE_AUTH_SCOPE_LENGTH = 32;
10
+ const SIGNATURE_DOMAIN = new TextEncoder().encode('blockcast-mmt-root-v1\0\0\0');
11
+ function requireBytes(name, value, length) {
12
+ if (value.byteLength !== length) {
13
+ throw new Error(`${name} must be ${length} bytes, got ${value.byteLength}`);
14
+ }
15
+ }
16
+ function requireU32(name, value) {
17
+ if (!Number.isInteger(value) || value < 0 || value > 0xffff_ffff) {
18
+ throw new Error(`${name} must be an unsigned 32-bit integer`);
19
+ }
20
+ }
21
+ function requireU64(name, value) {
22
+ if (value < 0n || value > 0xffffffffffffffffn) {
23
+ throw new Error(`${name} must be an unsigned 64-bit integer`);
24
+ }
25
+ }
26
+ function requireTrueLength(value) {
27
+ requireU32('trueLength', value);
28
+ if (value > SOURCE_AUTH_MAX_TRUE_LENGTH) {
29
+ throw new Error(`trueLength exceeds the ${SOURCE_AUTH_MAX_TRUE_LENGTH}-byte profile maximum`);
30
+ }
31
+ }
32
+ export function sourceAuthObjectDigest(object) {
33
+ return blake3(object);
34
+ }
35
+ export function sourceAuthLeafHash(groupId, objectId, digest, trueLength) {
36
+ requireU64('groupId', groupId);
37
+ requireU32('objectId', objectId);
38
+ requireBytes('digest', digest, 32);
39
+ requireTrueLength(trueLength);
40
+ const preimage = new Uint8Array(49);
41
+ const view = new DataView(preimage.buffer);
42
+ view.setBigUint64(1, groupId);
43
+ view.setUint32(9, objectId);
44
+ preimage.set(digest, 13);
45
+ view.setUint32(45, trueLength);
46
+ return blake3(preimage);
47
+ }
48
+ export function sourceAuthMerkleRoot(entries) {
49
+ if (entries.length === 0)
50
+ throw new Error('Merkle tree requires at least one object');
51
+ if (entries.length > SOURCE_AUTH_MAX_OBJECTS_PER_GROUP) {
52
+ throw new Error(`group exceeds ${SOURCE_AUTH_MAX_OBJECTS_PER_GROUP} objects`);
53
+ }
54
+ const groupId = entries[0].groupId;
55
+ const objectIds = new Set();
56
+ const ordered = [...entries].sort((left, right) => left.objectId - right.objectId);
57
+ let level = ordered.map((entry) => {
58
+ if (entry.groupId !== groupId)
59
+ throw new Error('Merkle entries must belong to one group');
60
+ if (objectIds.has(entry.objectId))
61
+ throw new Error(`duplicate objectId ${entry.objectId}`);
62
+ objectIds.add(entry.objectId);
63
+ return sourceAuthLeafHash(entry.groupId, entry.objectId, entry.digest, entry.trueLength);
64
+ });
65
+ while (level.length > 1) {
66
+ const parents = [];
67
+ for (let index = 0; index < level.length; index += 2) {
68
+ const left = level[index];
69
+ const right = level[index + 1] ?? left;
70
+ const preimage = new Uint8Array(65);
71
+ preimage[0] = 1;
72
+ preimage.set(left, 1);
73
+ preimage.set(right, 33);
74
+ parents.push(blake3(preimage));
75
+ }
76
+ level = parents;
77
+ }
78
+ return level[0];
79
+ }
80
+ export function trimRecoveredSourceAuthObject(recoveredSymbol, trueLength) {
81
+ requireTrueLength(trueLength);
82
+ if (trueLength > recoveredSymbol.byteLength) {
83
+ throw new Error(`true length ${trueLength} exceeds recovered object size ${recoveredSymbol.byteLength}`);
84
+ }
85
+ return recoveredSymbol.subarray(0, trueLength);
86
+ }
87
+ export function encodeSourceAuthObjectEntry(entry) {
88
+ requireU32('objectId', entry.objectId);
89
+ requireTrueLength(entry.trueLength);
90
+ requireU64('groupId', entry.groupId);
91
+ requireBytes('digest', entry.digest, 32);
92
+ const frame = new Uint8Array(SOURCE_AUTH_OBJECT_ENTRY_LENGTH);
93
+ const view = new DataView(frame.buffer);
94
+ frame[0] = SOURCE_AUTH_OBJECT_ENTRY_FRAME;
95
+ frame[1] = SOURCE_AUTH_MANIFEST_VERSION;
96
+ view.setBigUint64(4, entry.groupId);
97
+ view.setUint32(12, entry.objectId);
98
+ view.setUint32(16, entry.trueLength);
99
+ frame.set(entry.digest, 20);
100
+ return frame;
101
+ }
102
+ export function encodeSourceAuthGroupClose(close) {
103
+ requireU32('objectCount', close.objectCount);
104
+ if (close.objectCount === 0 || close.objectCount > SOURCE_AUTH_MAX_OBJECTS_PER_GROUP) {
105
+ throw new Error(`objectCount must be between 1 and ${SOURCE_AUTH_MAX_OBJECTS_PER_GROUP}`);
106
+ }
107
+ requireU64('groupId', close.groupId);
108
+ requireBytes('root', close.root, 32);
109
+ requireBytes('signature', close.signature, 64);
110
+ const frame = new Uint8Array(SOURCE_AUTH_GROUP_CLOSE_LENGTH);
111
+ const view = new DataView(frame.buffer);
112
+ frame[0] = SOURCE_AUTH_GROUP_CLOSE_FRAME;
113
+ frame[1] = SOURCE_AUTH_MANIFEST_VERSION;
114
+ view.setBigUint64(4, close.groupId);
115
+ view.setUint32(12, close.objectCount);
116
+ frame.set(close.root, 16);
117
+ frame.set(close.signature, 48);
118
+ return frame;
119
+ }
120
+ export function sourceAuthSignaturePreimage(authScope, groupId, objectCount, root) {
121
+ requireU32('objectCount', objectCount);
122
+ if (objectCount === 0 || objectCount > SOURCE_AUTH_MAX_OBJECTS_PER_GROUP) {
123
+ throw new Error(`objectCount must be between 1 and ${SOURCE_AUTH_MAX_OBJECTS_PER_GROUP}`);
124
+ }
125
+ requireU64('groupId', groupId);
126
+ requireBytes('authScope', authScope, SOURCE_AUTH_SCOPE_LENGTH);
127
+ requireBytes('root', root, 32);
128
+ const preimage = new Uint8Array(100);
129
+ const view = new DataView(preimage.buffer);
130
+ preimage.set(SIGNATURE_DOMAIN);
131
+ preimage.set(authScope, 24);
132
+ view.setBigUint64(56, groupId);
133
+ view.setUint32(64, objectCount);
134
+ preimage.set(root, 68);
135
+ return preimage;
136
+ }
137
+ export function decodeSourceAuthManifestFrame(frame) {
138
+ const frameType = frame[0];
139
+ const expectedLength = frameType === SOURCE_AUTH_OBJECT_ENTRY_FRAME
140
+ ? SOURCE_AUTH_OBJECT_ENTRY_LENGTH
141
+ : frameType === SOURCE_AUTH_GROUP_CLOSE_FRAME
142
+ ? SOURCE_AUTH_GROUP_CLOSE_LENGTH
143
+ : 0;
144
+ if (expectedLength === 0)
145
+ throw new Error(`unsupported manifest frame type ${frameType}`);
146
+ if (frame.byteLength !== expectedLength) {
147
+ throw new Error(`manifest frame has invalid length ${frame.byteLength} for type ${frameType}`);
148
+ }
149
+ if (frame[1] !== SOURCE_AUTH_MANIFEST_VERSION) {
150
+ throw new Error(`unsupported manifest version ${frame[1]}`);
151
+ }
152
+ if (frame[2] !== 0 || frame[3] !== 0)
153
+ throw new Error('manifest reserved bits must be zero');
154
+ const view = new DataView(frame.buffer, frame.byteOffset, frame.byteLength);
155
+ const groupId = view.getBigUint64(4);
156
+ if (frameType === SOURCE_AUTH_OBJECT_ENTRY_FRAME) {
157
+ const entry = {
158
+ kind: 'object',
159
+ groupId,
160
+ objectId: view.getUint32(12),
161
+ trueLength: view.getUint32(16),
162
+ digest: frame.slice(20, 52),
163
+ };
164
+ requireTrueLength(entry.trueLength);
165
+ return entry;
166
+ }
167
+ const close = {
168
+ kind: 'close',
169
+ groupId,
170
+ objectCount: view.getUint32(12),
171
+ root: frame.slice(16, 48),
172
+ signature: frame.slice(48, 112),
173
+ };
174
+ if (close.objectCount === 0 || close.objectCount > SOURCE_AUTH_MAX_OBJECTS_PER_GROUP) {
175
+ throw new Error(`objectCount must be between 1 and ${SOURCE_AUTH_MAX_OBJECTS_PER_GROUP}`);
176
+ }
177
+ return close;
178
+ }
179
+ //# sourceMappingURL=source-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-auth.js","sourceRoot":"","sources":["../src/source-auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ export type ManifestAuthMode = 'off' | 'shadow' | 'enforce';
2
+ export type MissingManifestPolicy = 'stall' | 'fallback-shadow';
3
+ export type ManifestFailureReason = 'sigInvalid' | 'digestMismatch' | 'manifestLate' | 'manifestAbsent' | 'verifierError';
4
+ export interface ManifestAuthConfig {
5
+ mode: ManifestAuthMode;
6
+ onMissingManifest: MissingManifestPolicy;
7
+ }
8
+ export interface ManifestObjectIdentity {
9
+ trackName: string;
10
+ /** MoQ group ids are u62; values above 2^53 must be passed as bigint. */
11
+ groupId: number | bigint;
12
+ objectId: number;
13
+ packetId?: number;
14
+ ssId?: number;
15
+ }
16
+ export interface ManifestFecBlockMapper {
17
+ readonly d: number;
18
+ derive(groupId: number, objectId: number): {
19
+ ssId: number;
20
+ };
21
+ }
22
+ export interface ManifestTrackContext {
23
+ broadcastNamespaceId: string;
24
+ trackName: string;
25
+ keyEpoch: number;
26
+ codec: string;
27
+ timing: string;
28
+ fecGeometry: string;
29
+ manifestFormatVersion: number;
30
+ /** Authenticated-catalog binding for the namespace, track, epoch, codec,
31
+ * timing, FEC geometry, and manifest version fields above. */
32
+ authScope: Uint8Array;
33
+ publicKey: Uint8Array;
34
+ bitrate: number;
35
+ groupDurationMs: number;
36
+ mapper: ManifestFecBlockMapper;
37
+ manifestChannelAuthenticated: boolean;
38
+ }
39
+ export interface ManifestVerificationStats {
40
+ verified: number;
41
+ failures: Record<ManifestFailureReason, number>;
42
+ quarantinedBytes: number;
43
+ }
44
+ export interface ManifestFailure {
45
+ trackName: string;
46
+ groupId: number | bigint;
47
+ objectId: number;
48
+ reason: ManifestFailureReason;
49
+ }
50
+ export interface ManifestAdmission {
51
+ action: 'play' | 'stall' | 'drop';
52
+ verified: boolean;
53
+ reason?: ManifestFailureReason;
54
+ }
55
+ type SignatureVerifier = (publicKey: Uint8Array, message: Uint8Array, signature: Uint8Array) => boolean;
56
+ export declare class ManifestVerifier {
57
+ #private;
58
+ constructor(options: {
59
+ manifestAuth: ManifestAuthConfig;
60
+ verifySignature: SignatureVerifier;
61
+ onFailure?: (failure: ManifestFailure) => void;
62
+ });
63
+ get config(): Readonly<ManifestAuthConfig>;
64
+ get stats(): ManifestVerificationStats;
65
+ setMode(mode: ManifestAuthMode): void;
66
+ registerTrack(context: ManifestTrackContext): void;
67
+ ingestManifestFrame(trackName: string, frameBytes: Uint8Array): void;
68
+ admitObject(identity: ManifestObjectIdentity, data: Uint8Array, release: () => void): ManifestAdmission;
69
+ dispose(): void;
70
+ }
71
+ export {};
72
+ //# sourceMappingURL=verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"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"}