@clawbureau/clawverify-core 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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +40 -0
  3. package/dist/crypto.d.ts +27 -0
  4. package/dist/crypto.d.ts.map +1 -0
  5. package/dist/crypto.js +124 -0
  6. package/dist/crypto.js.map +1 -0
  7. package/dist/index.d.ts +27 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +24 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/jcs.d.ts +13 -0
  12. package/dist/jcs.d.ts.map +1 -0
  13. package/dist/jcs.js +43 -0
  14. package/dist/jcs.js.map +1 -0
  15. package/dist/model-identity.d.ts +46 -0
  16. package/dist/model-identity.d.ts.map +1 -0
  17. package/dist/model-identity.js +233 -0
  18. package/dist/model-identity.js.map +1 -0
  19. package/dist/schema-registry.d.ts +99 -0
  20. package/dist/schema-registry.d.ts.map +1 -0
  21. package/dist/schema-registry.js +259 -0
  22. package/dist/schema-registry.js.map +1 -0
  23. package/dist/schema-validation.d.ts +35 -0
  24. package/dist/schema-validation.d.ts.map +1 -0
  25. package/dist/schema-validation.js +156 -0
  26. package/dist/schema-validation.js.map +1 -0
  27. package/dist/schema-validators.generated.d.ts +158 -0
  28. package/dist/schema-validators.generated.d.ts.map +1 -0
  29. package/dist/schema-validators.generated.js +19186 -0
  30. package/dist/schema-validators.generated.js.map +1 -0
  31. package/dist/types.d.ts +910 -0
  32. package/dist/types.d.ts.map +1 -0
  33. package/dist/types.js +33 -0
  34. package/dist/types.js.map +1 -0
  35. package/dist/verify-audit-result-attestation.d.ts +32 -0
  36. package/dist/verify-audit-result-attestation.d.ts.map +1 -0
  37. package/dist/verify-audit-result-attestation.js +396 -0
  38. package/dist/verify-audit-result-attestation.js.map +1 -0
  39. package/dist/verify-derivation-attestation.d.ts +30 -0
  40. package/dist/verify-derivation-attestation.d.ts.map +1 -0
  41. package/dist/verify-derivation-attestation.js +371 -0
  42. package/dist/verify-derivation-attestation.js.map +1 -0
  43. package/dist/verify-execution-attestation.d.ts +32 -0
  44. package/dist/verify-execution-attestation.d.ts.map +1 -0
  45. package/dist/verify-execution-attestation.js +578 -0
  46. package/dist/verify-execution-attestation.js.map +1 -0
  47. package/dist/verify-export-bundle.d.ts +14 -0
  48. package/dist/verify-export-bundle.d.ts.map +1 -0
  49. package/dist/verify-export-bundle.js +307 -0
  50. package/dist/verify-export-bundle.js.map +1 -0
  51. package/dist/verify-log-inclusion-proof.d.ts +16 -0
  52. package/dist/verify-log-inclusion-proof.d.ts.map +1 -0
  53. package/dist/verify-log-inclusion-proof.js +216 -0
  54. package/dist/verify-log-inclusion-proof.js.map +1 -0
  55. package/dist/verify-proof-bundle.d.ts +48 -0
  56. package/dist/verify-proof-bundle.d.ts.map +1 -0
  57. package/dist/verify-proof-bundle.js +1708 -0
  58. package/dist/verify-proof-bundle.js.map +1 -0
  59. package/dist/verify-receipt.d.ts +30 -0
  60. package/dist/verify-receipt.d.ts.map +1 -0
  61. package/dist/verify-receipt.js +408 -0
  62. package/dist/verify-receipt.js.map +1 -0
  63. package/dist/verify-web-receipt.d.ts +21 -0
  64. package/dist/verify-web-receipt.d.ts.map +1 -0
  65. package/dist/verify-web-receipt.js +341 -0
  66. package/dist/verify-web-receipt.js.map +1 -0
  67. package/package.json +54 -0
@@ -0,0 +1,307 @@
1
+ /**
2
+ * Export Bundle Verification
3
+ * POHVN-US-007: Audit-ready export bundles (offline verifiability)
4
+ */
5
+ import { isValidDidFormat, isValidIsoDate } from './schema-registry.js';
6
+ import { base64UrlDecode, base64UrlEncode, extractPublicKeyFromDidKey, verifySignature, } from './crypto.js';
7
+ import { validateExportBundleV1 } from './schema-validation.js';
8
+ import { verifyProofBundle } from './verify-proof-bundle.js';
9
+ import { verifyExecutionAttestation } from './verify-execution-attestation.js';
10
+ import { verifyDerivationAttestation } from './verify-derivation-attestation.js';
11
+ import { verifyAuditResultAttestation } from './verify-audit-result-attestation.js';
12
+ import { jcsCanonicalize } from './jcs.js';
13
+ function utf8Bytes(input) {
14
+ return new TextEncoder().encode(input);
15
+ }
16
+ async function sha256B64u(input) {
17
+ const digest = await crypto.subtle.digest('SHA-256', input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength));
18
+ return base64UrlEncode(new Uint8Array(digest));
19
+ }
20
+ function manifestPathFor(kind, index) {
21
+ if (index === undefined)
22
+ return `artifacts/${kind}.json`;
23
+ return `artifacts/${kind}/${index}.json`;
24
+ }
25
+ async function manifestEntry(path, value) {
26
+ const canonical = jcsCanonicalize(value);
27
+ const bytes = utf8Bytes(canonical);
28
+ return {
29
+ path,
30
+ sha256_b64u: await sha256B64u(bytes),
31
+ content_type: 'application/json',
32
+ size_bytes: bytes.byteLength,
33
+ };
34
+ }
35
+ async function computeExpectedManifestEntries(bundle) {
36
+ const entries = [];
37
+ entries.push(await manifestEntry(manifestPathFor('proof_bundle_envelope'), bundle.artifacts.proof_bundle_envelope));
38
+ const execution = bundle.artifacts.execution_attestation_envelopes ?? [];
39
+ for (let i = 0; i < execution.length; i++) {
40
+ entries.push(await manifestEntry(manifestPathFor('execution_attestation_envelopes', i), execution[i]));
41
+ }
42
+ const derivation = bundle.artifacts.derivation_attestation_envelopes ?? [];
43
+ for (let i = 0; i < derivation.length; i++) {
44
+ entries.push(await manifestEntry(manifestPathFor('derivation_attestation_envelopes', i), derivation[i]));
45
+ }
46
+ const audit = bundle.artifacts.audit_result_attestation_envelopes ?? [];
47
+ for (let i = 0; i < audit.length; i++) {
48
+ entries.push(await manifestEntry(manifestPathFor('audit_result_attestation_envelopes', i), audit[i]));
49
+ }
50
+ return entries.sort((a, b) => a.path.localeCompare(b.path));
51
+ }
52
+ function normalizeManifestEntries(entries) {
53
+ return [...entries].sort((a, b) => a.path.localeCompare(b.path));
54
+ }
55
+ function firstRunIdFromProofBundle(bundle) {
56
+ const events = bundle.artifacts.proof_bundle_envelope?.payload?.event_chain;
57
+ if (!Array.isArray(events) || events.length === 0)
58
+ return null;
59
+ const runId = events[0]?.run_id;
60
+ return typeof runId === 'string' && runId.length > 0 ? runId : null;
61
+ }
62
+ function signableBundleView(bundle) {
63
+ const out = {
64
+ export_version: bundle.export_version,
65
+ export_id: bundle.export_id,
66
+ created_at: bundle.created_at,
67
+ issuer_did: bundle.issuer_did,
68
+ manifest: bundle.manifest,
69
+ artifacts: bundle.artifacts,
70
+ issued_at: bundle.issued_at,
71
+ };
72
+ if (bundle.metadata !== undefined) {
73
+ out.metadata = bundle.metadata;
74
+ }
75
+ return out;
76
+ }
77
+ function invalid(now, reason, error, extras = {}) {
78
+ return {
79
+ result: {
80
+ status: 'INVALID',
81
+ reason,
82
+ envelope_type: 'export_bundle',
83
+ verified_at: now,
84
+ },
85
+ error,
86
+ ...extras,
87
+ };
88
+ }
89
+ function valid(now, bundle, extras = {}) {
90
+ return {
91
+ result: {
92
+ status: 'VALID',
93
+ reason: 'Export bundle verified successfully',
94
+ envelope_type: 'export_bundle',
95
+ signer_did: bundle.issuer_did,
96
+ verified_at: now,
97
+ },
98
+ export_id: bundle.export_id,
99
+ bundle_hash_b64u: bundle.bundle_hash_b64u,
100
+ ...extras,
101
+ };
102
+ }
103
+ export async function verifyExportBundle(bundleInput, options = {}) {
104
+ const now = new Date().toISOString();
105
+ const schemaResult = validateExportBundleV1(bundleInput);
106
+ if (!schemaResult.valid) {
107
+ return invalid(now, schemaResult.message, {
108
+ code: 'SCHEMA_VALIDATION_FAILED',
109
+ message: schemaResult.message,
110
+ field: schemaResult.field,
111
+ });
112
+ }
113
+ const bundle = bundleInput;
114
+ if (!isValidDidFormat(bundle.issuer_did)) {
115
+ return invalid(now, 'Invalid issuer DID format', {
116
+ code: 'INVALID_DID_FORMAT',
117
+ message: 'issuer_did must be a valid DID string',
118
+ field: 'issuer_did',
119
+ });
120
+ }
121
+ if (!isValidIsoDate(bundle.created_at) || !isValidIsoDate(bundle.issued_at)) {
122
+ return invalid(now, 'Invalid date fields', {
123
+ code: 'MALFORMED_ENVELOPE',
124
+ message: 'created_at and issued_at must be valid ISO 8601 strings',
125
+ field: !isValidIsoDate(bundle.created_at) ? 'created_at' : 'issued_at',
126
+ });
127
+ }
128
+ // 1) Verify manifest hashes/content-addressing against included artifacts.
129
+ const providedEntries = normalizeManifestEntries(bundle.manifest.entries);
130
+ const expectedEntries = await computeExpectedManifestEntries(bundle);
131
+ const pathSet = new Set();
132
+ for (const e of providedEntries) {
133
+ if (pathSet.has(e.path)) {
134
+ return invalid(now, 'Manifest contains duplicate path entries', {
135
+ code: 'MALFORMED_ENVELOPE',
136
+ message: `Duplicate manifest path: ${e.path}`,
137
+ field: 'manifest.entries.path',
138
+ });
139
+ }
140
+ pathSet.add(e.path);
141
+ }
142
+ if (providedEntries.length !== expectedEntries.length) {
143
+ return invalid(now, 'Manifest entry count mismatch', {
144
+ code: 'MISSING_REQUIRED_FIELD',
145
+ message: `manifest.entries count (${providedEntries.length}) does not match expected artifact count (${expectedEntries.length})`,
146
+ field: 'manifest.entries',
147
+ });
148
+ }
149
+ const providedMap = new Map(providedEntries.map((e) => [e.path, e]));
150
+ for (const expected of expectedEntries) {
151
+ const actual = providedMap.get(expected.path);
152
+ if (!actual) {
153
+ return invalid(now, 'Manifest missing expected artifact path', {
154
+ code: 'MISSING_REQUIRED_FIELD',
155
+ message: `manifest is missing expected path ${expected.path}`,
156
+ field: 'manifest.entries.path',
157
+ });
158
+ }
159
+ if (actual.sha256_b64u !== expected.sha256_b64u) {
160
+ return invalid(now, 'Manifest hash mismatch', {
161
+ code: 'HASH_MISMATCH',
162
+ message: `manifest hash mismatch for ${expected.path}`,
163
+ field: `manifest.entries[${expected.path}].sha256_b64u`,
164
+ });
165
+ }
166
+ if (actual.content_type !== expected.content_type) {
167
+ return invalid(now, 'Manifest content type mismatch', {
168
+ code: 'MALFORMED_ENVELOPE',
169
+ message: `manifest content_type mismatch for ${expected.path}`,
170
+ field: `manifest.entries[${expected.path}].content_type`,
171
+ });
172
+ }
173
+ if (actual.size_bytes !== expected.size_bytes) {
174
+ return invalid(now, 'Manifest size mismatch', {
175
+ code: 'HASH_MISMATCH',
176
+ message: `manifest size_bytes mismatch for ${expected.path}`,
177
+ field: `manifest.entries[${expected.path}].size_bytes`,
178
+ });
179
+ }
180
+ }
181
+ // 2) Verify export bundle hash + signature.
182
+ const computedBundleHash = await sha256B64u(utf8Bytes(jcsCanonicalize(signableBundleView(bundle))));
183
+ if (computedBundleHash !== bundle.bundle_hash_b64u) {
184
+ return invalid(now, 'Export bundle hash mismatch', {
185
+ code: 'HASH_MISMATCH',
186
+ message: 'Computed bundle hash does not match bundle_hash_b64u',
187
+ field: 'bundle_hash_b64u',
188
+ });
189
+ }
190
+ const exportPublicKey = extractPublicKeyFromDidKey(bundle.issuer_did);
191
+ if (!exportPublicKey) {
192
+ return invalid(now, 'Could not extract public key from issuer DID', {
193
+ code: 'INVALID_DID_FORMAT',
194
+ message: 'issuer_did must be did:key with Ed25519 multicodec key',
195
+ field: 'issuer_did',
196
+ });
197
+ }
198
+ let bundleSigBytes;
199
+ try {
200
+ bundleSigBytes = base64UrlDecode(bundle.signature_b64u);
201
+ }
202
+ catch {
203
+ return invalid(now, 'Invalid export bundle signature encoding', {
204
+ code: 'MALFORMED_ENVELOPE',
205
+ message: 'signature_b64u is not valid base64url',
206
+ field: 'signature_b64u',
207
+ });
208
+ }
209
+ const bundleSigOk = await verifySignature('Ed25519', exportPublicKey, bundleSigBytes, utf8Bytes(bundle.bundle_hash_b64u));
210
+ if (!bundleSigOk) {
211
+ return invalid(now, 'Export bundle signature verification failed', {
212
+ code: 'SIGNATURE_INVALID',
213
+ message: 'signature_b64u does not verify bundle_hash_b64u using issuer_did key',
214
+ field: 'signature_b64u',
215
+ });
216
+ }
217
+ // 3) Verify included envelopes with existing verifiers (offline, no network calls).
218
+ const proofBundleOut = await verifyProofBundle(bundle.artifacts.proof_bundle_envelope, {
219
+ allowlistedReceiptSignerDids: options.allowlistedReceiptSignerDids,
220
+ allowlistedAttesterDids: options.allowlistedAttesterDids,
221
+ });
222
+ if (proofBundleOut.result.status !== 'VALID') {
223
+ return invalid(now, `Proof bundle verification failed: ${proofBundleOut.result.reason}`, proofBundleOut.error ?? {
224
+ code: 'MALFORMED_ENVELOPE',
225
+ message: 'proof_bundle_envelope failed verification',
226
+ field: 'artifacts.proof_bundle_envelope',
227
+ }, {
228
+ export_id: bundle.export_id,
229
+ bundle_hash_b64u: bundle.bundle_hash_b64u,
230
+ });
231
+ }
232
+ const expectedProofBundleHash = bundle.artifacts.proof_bundle_envelope.payload_hash_b64u;
233
+ const expectedRunId = firstRunIdFromProofBundle(bundle);
234
+ const expectedAgentDid = bundle.artifacts.proof_bundle_envelope.payload.agent_did;
235
+ const execution = bundle.artifacts.execution_attestation_envelopes ?? [];
236
+ for (let i = 0; i < execution.length; i++) {
237
+ const out = await verifyExecutionAttestation(execution[i], {
238
+ allowlistedSignerDids: options.allowlistedExecutionAttestationSignerDids,
239
+ });
240
+ if (out.result.status !== 'VALID') {
241
+ return invalid(now, `Execution attestation verification failed (index ${i})`, out.error ?? {
242
+ code: 'MALFORMED_ENVELOPE',
243
+ message: 'execution_attestation_envelope failed verification',
244
+ field: `artifacts.execution_attestation_envelopes[${i}]`,
245
+ });
246
+ }
247
+ if (out.proof_bundle_hash_b64u !== expectedProofBundleHash) {
248
+ return invalid(now, 'Execution attestation proof bundle hash mismatch', {
249
+ code: 'HASH_MISMATCH',
250
+ message: `execution_attestation proof_bundle_hash_b64u mismatch at index ${i}`,
251
+ field: `artifacts.execution_attestation_envelopes[${i}].payload.proof_bundle_hash_b64u`,
252
+ });
253
+ }
254
+ if (expectedRunId && out.run_id !== expectedRunId) {
255
+ return invalid(now, 'Execution attestation run_id mismatch', {
256
+ code: 'HASH_MISMATCH',
257
+ message: `execution_attestation run_id mismatch at index ${i}`,
258
+ field: `artifacts.execution_attestation_envelopes[${i}].payload.run_id`,
259
+ });
260
+ }
261
+ if (out.agent_did !== expectedAgentDid) {
262
+ return invalid(now, 'Execution attestation agent_did mismatch', {
263
+ code: 'HASH_MISMATCH',
264
+ message: `execution_attestation agent_did mismatch at index ${i}`,
265
+ field: `artifacts.execution_attestation_envelopes[${i}].payload.agent_did`,
266
+ });
267
+ }
268
+ }
269
+ const derivations = bundle.artifacts.derivation_attestation_envelopes ?? [];
270
+ for (let i = 0; i < derivations.length; i++) {
271
+ const out = await verifyDerivationAttestation(derivations[i], {
272
+ allowlistedSignerDids: options.allowlistedDerivationAttestationSignerDids,
273
+ });
274
+ if (out.result.status !== 'VALID') {
275
+ return invalid(now, `Derivation attestation verification failed (index ${i})`, out.error ?? {
276
+ code: 'MALFORMED_ENVELOPE',
277
+ message: 'derivation_attestation_envelope failed verification',
278
+ field: `artifacts.derivation_attestation_envelopes[${i}]`,
279
+ });
280
+ }
281
+ }
282
+ const audits = bundle.artifacts.audit_result_attestation_envelopes ?? [];
283
+ for (let i = 0; i < audits.length; i++) {
284
+ const out = await verifyAuditResultAttestation(audits[i], {
285
+ allowlistedSignerDids: options.allowlistedAuditResultAttestationSignerDids,
286
+ });
287
+ if (out.result.status !== 'VALID') {
288
+ return invalid(now, `Audit-result attestation verification failed (index ${i})`, out.error ?? {
289
+ code: 'MALFORMED_ENVELOPE',
290
+ message: 'audit_result_attestation_envelope failed verification',
291
+ field: `artifacts.audit_result_attestation_envelopes[${i}]`,
292
+ });
293
+ }
294
+ }
295
+ return valid(now, bundle, {
296
+ manifest_entries_verified: expectedEntries.length,
297
+ verified_components: {
298
+ proof_bundle_valid: true,
299
+ execution_attestations_verified: execution.length,
300
+ derivation_attestations_verified: derivations.length,
301
+ audit_result_attestations_verified: audits.length,
302
+ },
303
+ proof_tier: proofBundleOut.result.proof_tier,
304
+ model_identity_tier: proofBundleOut.result.model_identity_tier,
305
+ });
306
+ }
307
+ //# sourceMappingURL=verify-export-bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-export-bundle.js","sourceRoot":"","sources":["../src/verify-export-bundle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { VerificationError } from './types.js';
2
+ export interface InclusionProofVerification {
3
+ valid: boolean;
4
+ error?: VerificationError;
5
+ reason?: string;
6
+ }
7
+ /**
8
+ * Verify `log_inclusion_proof.v1`.
9
+ *
10
+ * Fail-closed expectations:
11
+ * - strict schema
12
+ * - valid did:key root signature over root_hash_b64u
13
+ * - valid Merkle path (sha256(left||right), duplicate-last at generation time)
14
+ */
15
+ export declare function verifyLogInclusionProof(proof: unknown): Promise<InclusionProofVerification>;
16
+ //# sourceMappingURL=verify-log-inclusion-proof.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-log-inclusion-proof.d.ts","sourceRoot":"","sources":["../src/verify-log-inclusion-proof.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA6DpD,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,0BAA0B,CAAC,CA2LrC"}
@@ -0,0 +1,216 @@
1
+ import { base64UrlDecode, base64UrlEncode, extractPublicKeyFromDidKey, verifySignature, } from './crypto.js';
2
+ import { isValidDidFormat, isValidIsoDate } from './schema-registry.js';
3
+ import { validateLogInclusionProofV1 } from './schema-validation.js';
4
+ function isRecord(value) {
5
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
6
+ }
7
+ function concatBytes(a, b) {
8
+ const out = new Uint8Array(a.length + b.length);
9
+ out.set(a, 0);
10
+ out.set(b, a.length);
11
+ return out;
12
+ }
13
+ async function sha256(bytes) {
14
+ const digest = await crypto.subtle.digest('SHA-256', bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength));
15
+ return new Uint8Array(digest);
16
+ }
17
+ function expectedAuditPathLength(treeSize) {
18
+ let n = treeSize;
19
+ let len = 0;
20
+ while (n > 1) {
21
+ n = Math.floor((n + 1) / 2);
22
+ len += 1;
23
+ }
24
+ return len;
25
+ }
26
+ function decodeLeafIndex(metadata) {
27
+ if (!isRecord(metadata))
28
+ return null;
29
+ const index = metadata.leaf_index;
30
+ if (!Number.isInteger(index) || index < 0)
31
+ return null;
32
+ return index;
33
+ }
34
+ /**
35
+ * Verify `log_inclusion_proof.v1`.
36
+ *
37
+ * Fail-closed expectations:
38
+ * - strict schema
39
+ * - valid did:key root signature over root_hash_b64u
40
+ * - valid Merkle path (sha256(left||right), duplicate-last at generation time)
41
+ */
42
+ export async function verifyLogInclusionProof(proof) {
43
+ const schemaResult = validateLogInclusionProofV1(proof);
44
+ if (!schemaResult.valid) {
45
+ return {
46
+ valid: false,
47
+ reason: schemaResult.message,
48
+ error: {
49
+ code: 'SCHEMA_VALIDATION_FAILED',
50
+ message: schemaResult.message,
51
+ field: schemaResult.field,
52
+ },
53
+ };
54
+ }
55
+ const p = proof;
56
+ if (!isValidIsoDate(p.root_published_at)) {
57
+ return {
58
+ valid: false,
59
+ reason: 'Invalid root_published_at date format',
60
+ error: {
61
+ code: 'INCLUSION_PROOF_INVALID',
62
+ message: 'root_published_at must be a valid ISO 8601 date',
63
+ field: 'root_published_at',
64
+ },
65
+ };
66
+ }
67
+ const leafIndex = decodeLeafIndex(p.metadata);
68
+ if (leafIndex === null) {
69
+ return {
70
+ valid: false,
71
+ reason: 'Missing metadata.leaf_index required for ordered Merkle verification',
72
+ error: {
73
+ code: 'INCLUSION_PROOF_INVALID',
74
+ message: 'inclusion_proof.metadata.leaf_index (integer) is required for ordered Merkle verification',
75
+ field: 'metadata.leaf_index',
76
+ },
77
+ };
78
+ }
79
+ if (!Number.isInteger(p.tree_size) || p.tree_size <= 0) {
80
+ return {
81
+ valid: false,
82
+ reason: 'tree_size must be a positive integer',
83
+ error: {
84
+ code: 'INCLUSION_PROOF_INVALID',
85
+ message: 'tree_size must be a positive integer for inclusion proofs',
86
+ field: 'tree_size',
87
+ },
88
+ };
89
+ }
90
+ if (leafIndex >= p.tree_size) {
91
+ return {
92
+ valid: false,
93
+ reason: 'leaf_index out of bounds',
94
+ error: {
95
+ code: 'INCLUSION_PROOF_INVALID',
96
+ message: 'metadata.leaf_index must be less than tree_size',
97
+ field: 'metadata.leaf_index',
98
+ },
99
+ };
100
+ }
101
+ const expectedPathLen = expectedAuditPathLength(p.tree_size);
102
+ if (p.audit_path.length !== expectedPathLen) {
103
+ return {
104
+ valid: false,
105
+ reason: 'audit_path length does not match tree_size',
106
+ error: {
107
+ code: 'INCLUSION_PROOF_INVALID',
108
+ message: `audit_path length must be ${expectedPathLen} for tree_size=${p.tree_size}`,
109
+ field: 'audit_path',
110
+ },
111
+ };
112
+ }
113
+ // Verify root signature first.
114
+ if (!isValidDidFormat(p.root_signature.signer_did)) {
115
+ return {
116
+ valid: false,
117
+ reason: 'Invalid root signature DID format',
118
+ error: {
119
+ code: 'INVALID_DID_FORMAT',
120
+ message: 'root_signature.signer_did must be a valid DID',
121
+ field: 'root_signature.signer_did',
122
+ },
123
+ };
124
+ }
125
+ const publicKeyBytes = extractPublicKeyFromDidKey(p.root_signature.signer_did);
126
+ if (!publicKeyBytes) {
127
+ return {
128
+ valid: false,
129
+ reason: 'Could not extract public key from root signature DID',
130
+ error: {
131
+ code: 'INVALID_DID_FORMAT',
132
+ message: 'root_signature.signer_did must be did:key with Ed25519 multicodec',
133
+ field: 'root_signature.signer_did',
134
+ },
135
+ };
136
+ }
137
+ try {
138
+ const sigBytes = base64UrlDecode(p.root_signature.sig_b64u);
139
+ const msgBytes = new TextEncoder().encode(p.root_hash_b64u);
140
+ const ok = await verifySignature('Ed25519', publicKeyBytes, sigBytes, msgBytes);
141
+ if (!ok) {
142
+ return {
143
+ valid: false,
144
+ reason: 'Root signature verification failed',
145
+ error: {
146
+ code: 'SIGNATURE_INVALID',
147
+ message: 'root_signature.sig_b64u does not verify root_hash_b64u',
148
+ field: 'root_signature.sig_b64u',
149
+ },
150
+ };
151
+ }
152
+ }
153
+ catch {
154
+ return {
155
+ valid: false,
156
+ reason: 'Root signature verification error',
157
+ error: {
158
+ code: 'SIGNATURE_INVALID',
159
+ message: 'Failed to verify root_signature.sig_b64u',
160
+ field: 'root_signature.sig_b64u',
161
+ },
162
+ };
163
+ }
164
+ // Verify Merkle inclusion path.
165
+ let current;
166
+ try {
167
+ current = base64UrlDecode(p.leaf_hash_b64u);
168
+ }
169
+ catch {
170
+ return {
171
+ valid: false,
172
+ reason: 'Invalid leaf hash encoding',
173
+ error: {
174
+ code: 'INCLUSION_PROOF_INVALID',
175
+ message: 'leaf_hash_b64u is not valid base64url',
176
+ field: 'leaf_hash_b64u',
177
+ },
178
+ };
179
+ }
180
+ let index = leafIndex;
181
+ for (const siblingHash of p.audit_path) {
182
+ let sibling;
183
+ try {
184
+ sibling = base64UrlDecode(siblingHash);
185
+ }
186
+ catch {
187
+ return {
188
+ valid: false,
189
+ reason: 'Invalid sibling hash encoding in audit_path',
190
+ error: {
191
+ code: 'INCLUSION_PROOF_INVALID',
192
+ message: 'audit_path entries must be valid base64url strings',
193
+ field: 'audit_path',
194
+ },
195
+ };
196
+ }
197
+ current =
198
+ index % 2 === 0
199
+ ? await sha256(concatBytes(current, sibling))
200
+ : await sha256(concatBytes(sibling, current));
201
+ index = Math.floor(index / 2);
202
+ }
203
+ const computedRoot = base64UrlEncode(current);
204
+ if (computedRoot !== p.root_hash_b64u) {
205
+ return {
206
+ valid: false,
207
+ reason: 'Computed Merkle root does not match proof root',
208
+ error: {
209
+ code: 'INCLUSION_PROOF_INVALID',
210
+ message: 'Merkle audit path does not resolve to root_hash_b64u',
211
+ },
212
+ };
213
+ }
214
+ return { valid: true, reason: 'Inclusion proof verified successfully' };
215
+ }
216
+ //# sourceMappingURL=verify-log-inclusion-proof.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-log-inclusion-proof.js","sourceRoot":"","sources":["../src/verify-log-inclusion-proof.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Proof Bundle Verification
3
+ * CVF-US-007: Verify proof bundles for trust tier computation
4
+ * POH-US-003: Validate proof bundles against PoH schema, verify receipts
5
+ * with clawproxy DID, verify event-chain hash linkage, and
6
+ * return trust tier based on validated components.
7
+ *
8
+ * Validates:
9
+ * - Proof bundle payload against PoH schema (proof_bundle.v1)
10
+ * - URM (Universal Resource Manifest) structure
11
+ * - Event chain hash linkage and run_id consistency
12
+ * - Gateway receipt envelopes (cryptographic verification)
13
+ * - Attestations
14
+ *
15
+ * Computes trust tier based on which components are present and valid.
16
+ * Fail-closed: unknown or malformed payloads always result in 'unknown' tier.
17
+ */
18
+ import type { ProofBundleVerificationResult, VerificationError } from './types.js';
19
+ export interface ProofBundleVerifierOptions {
20
+ /** Allowlisted gateway receipt signer DIDs (did:key:...). */
21
+ allowlistedReceiptSignerDids?: readonly string[];
22
+ /** Allowlisted attester DIDs for proof bundle attestations (did:key:...). */
23
+ allowlistedAttesterDids?: readonly string[];
24
+ /**
25
+ * Optional materialized URM document (JSON object).
26
+ *
27
+ * POH-US-015: If provided, clawverify will:
28
+ * - validate the URM against the strict schema (urm.v1)
29
+ * - hash it (SHA-256 over JSON bytes) and compare to payload.urm.resource_hash_b64u
30
+ *
31
+ * If the proof bundle contains a URM reference but no `urm` is provided,
32
+ * verification fails closed (result.status=INVALID).
33
+ */
34
+ urm?: unknown;
35
+ }
36
+ /**
37
+ * Verify a proof bundle envelope
38
+ *
39
+ * Acceptance Criteria:
40
+ * - Validate URM + event chain + receipts + attestations
41
+ * - Fail closed on unknown schema/version
42
+ * - Return computed trust tier
43
+ */
44
+ export declare function verifyProofBundle(envelope: unknown, options?: ProofBundleVerifierOptions): Promise<{
45
+ result: ProofBundleVerificationResult;
46
+ error?: VerificationError;
47
+ }>;
48
+ //# sourceMappingURL=verify-proof-bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-proof-bundle.d.ts","sourceRoot":"","sources":["../src/verify-proof-bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAGV,6BAA6B,EAC7B,iBAAiB,EAOlB,MAAM,YAAY,CAAC;AA0BpB,MAAM,WAAW,0BAA0B;IACzC,6DAA6D;IAC7D,4BAA4B,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAEjD,6EAA6E;IAC7E,uBAAuB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAE5C;;;;;;;;;OASG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAimBD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,OAAO,EACjB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC;IAAE,MAAM,EAAE,6BAA6B,CAAC;IAAC,KAAK,CAAC,EAAE,iBAAiB,CAAA;CAAE,CAAC,CAgyC/E"}