usertrust-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.
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Deterministic JSON canonicalization for hash computation.
3
+ * Sorts object keys alphabetically at every nesting level.
4
+ * Strips undefined values. Preserves null. Arrays keep order.
5
+ *
6
+ * INTENTIONAL DUPLICATION: This is a zero-dep copy for the usertrust-verify
7
+ * package. Do NOT import from usertrust.
8
+ */
9
+ export declare function canonicalize(value: unknown): string;
10
+ //# sourceMappingURL=canonical.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../src/canonical.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAcnD"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Deterministic JSON canonicalization for hash computation.
3
+ * Sorts object keys alphabetically at every nesting level.
4
+ * Strips undefined values. Preserves null. Arrays keep order.
5
+ *
6
+ * INTENTIONAL DUPLICATION: This is a zero-dep copy for the usertrust-verify
7
+ * package. Do NOT import from usertrust.
8
+ */
9
+ export function canonicalize(value) {
10
+ if (value === null || value === undefined)
11
+ return JSON.stringify(value);
12
+ if (typeof value !== "object")
13
+ return JSON.stringify(value);
14
+ if (Array.isArray(value)) {
15
+ return `[${value.map((v) => canonicalize(v)).join(",")}]`;
16
+ }
17
+ const obj = value;
18
+ const keys = Object.keys(obj).sort();
19
+ const parts = [];
20
+ for (const key of keys) {
21
+ if (obj[key] === undefined)
22
+ continue;
23
+ parts.push(`${JSON.stringify(key)}:${canonicalize(obj[key])}`);
24
+ }
25
+ return `{${parts.join(",")}}`;
26
+ }
27
+ //# sourceMappingURL=canonical.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical.js","sourceRoot":"","sources":["../src/canonical.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IAC1C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACxE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAC3D,CAAC;IACD,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS;YAAE,SAAS;QACrC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const GENESIS_HASH = "0000000000000000000000000000000000000000000000000000000000000000";
2
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,qEAAqE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const GENESIS_HASH = "0000000000000000000000000000000000000000000000000000000000000000";
2
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,kEAAkE,CAAC"}
@@ -0,0 +1,21 @@
1
+ export { canonicalize } from "./canonical.js";
2
+ export { GENESIS_HASH } from "./constants.js";
3
+ export { verifyChain, buildMerkleTree, hashLeaf, hashInternal, generateInclusionProof, verifyInclusionProof, generateConsistencyProof, verifyConsistencyProof, type ChainVerificationResult, type MerkleSibling, type MerkleInclusionProof, type MerkleConsistencyProof, } from "./verify.js";
4
+ export interface VaultVerificationResult {
5
+ valid: boolean;
6
+ errors: string[];
7
+ chainLength: number;
8
+ validHashes: number;
9
+ merkleRoot: string | null;
10
+ firstEvent: string | null;
11
+ lastEvent: string | null;
12
+ }
13
+ /**
14
+ * Verify an entire `.usertrust` vault directory.
15
+ *
16
+ * Finds all `events.jsonl` files under `<vaultPath>/audit/`, verifies each
17
+ * chain, computes a Merkle root over all event hashes, and returns a
18
+ * consolidated report.
19
+ */
20
+ export declare function verifyVault(vaultPath: string): VaultVerificationResult;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EACN,WAAW,EACX,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EACxB,sBAAsB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,GAC3B,MAAM,aAAa,CAAC;AAIrB,MAAM,WAAW,uBAAuB;IACvC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,uBAAuB,CAqGtE"}
package/dist/index.js ADDED
@@ -0,0 +1,107 @@
1
+ // usertrust-verify — Standalone Audit Verification (zero dependencies)
2
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { buildMerkleTree, verifyChain } from "./verify.js";
5
+ export { canonicalize } from "./canonical.js";
6
+ export { GENESIS_HASH } from "./constants.js";
7
+ export { verifyChain, buildMerkleTree, hashLeaf, hashInternal, generateInclusionProof, verifyInclusionProof, generateConsistencyProof, verifyConsistencyProof, } from "./verify.js";
8
+ /**
9
+ * Verify an entire `.usertrust` vault directory.
10
+ *
11
+ * Finds all `events.jsonl` files under `<vaultPath>/audit/`, verifies each
12
+ * chain, computes a Merkle root over all event hashes, and returns a
13
+ * consolidated report.
14
+ */
15
+ export function verifyVault(vaultPath) {
16
+ const auditDir = join(vaultPath, "audit");
17
+ const errors = [];
18
+ let totalEvents = 0;
19
+ let totalValid = 0;
20
+ let firstEvent = null;
21
+ let lastEvent = null;
22
+ const allHashes = [];
23
+ // Find all events.jsonl files
24
+ const logPaths = [];
25
+ const mainLog = join(auditDir, "events.jsonl");
26
+ if (existsSync(mainLog)) {
27
+ logPaths.push(mainLog);
28
+ }
29
+ // Also check for rotated segment files
30
+ if (existsSync(auditDir)) {
31
+ try {
32
+ const entries = readdirSync(auditDir);
33
+ for (const entry of entries) {
34
+ if (entry.endsWith(".jsonl") && entry !== "events.jsonl") {
35
+ logPaths.push(join(auditDir, entry));
36
+ }
37
+ }
38
+ }
39
+ catch {
40
+ // Directory read failure — non-fatal
41
+ }
42
+ }
43
+ if (logPaths.length === 0) {
44
+ if (!existsSync(auditDir)) {
45
+ errors.push(`Audit directory not found: ${auditDir}`);
46
+ }
47
+ return {
48
+ valid: errors.length === 0,
49
+ errors,
50
+ chainLength: 0,
51
+ validHashes: 0,
52
+ merkleRoot: null,
53
+ firstEvent: null,
54
+ lastEvent: null,
55
+ };
56
+ }
57
+ for (const logPath of logPaths) {
58
+ const result = verifyChain(logPath);
59
+ totalEvents += result.eventsVerified;
60
+ if (result.errors.length > 0) {
61
+ for (const err of result.errors) {
62
+ errors.push(err);
63
+ }
64
+ }
65
+ else {
66
+ totalValid += result.eventsVerified;
67
+ }
68
+ // Extract event hashes and timestamps for the report
69
+ if (existsSync(logPath)) {
70
+ const content = readFileSync(logPath, "utf-8").trim();
71
+ if (content) {
72
+ const lines = content.split("\n").filter((l) => l.trim());
73
+ for (const line of lines) {
74
+ try {
75
+ const event = JSON.parse(line);
76
+ allHashes.push(event.hash);
77
+ if (event.timestamp) {
78
+ if (firstEvent === null) {
79
+ firstEvent = event.timestamp;
80
+ }
81
+ lastEvent = event.timestamp;
82
+ }
83
+ }
84
+ catch {
85
+ // Already reported by verifyChain
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+ // Compute Merkle root over all event hashes
92
+ let merkleRoot = null;
93
+ if (allHashes.length > 0) {
94
+ const tree = buildMerkleTree(allHashes);
95
+ merkleRoot = tree.root ?? null;
96
+ }
97
+ return {
98
+ valid: errors.length === 0,
99
+ errors,
100
+ chainLength: totalEvents,
101
+ validHashes: totalValid,
102
+ merkleRoot,
103
+ firstEvent,
104
+ lastEvent,
105
+ };
106
+ }
107
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Audit Chain Verifier + Merkle Proofs — Zero-dependency standalone
3
+ *
4
+ * INTENTIONAL DUPLICATION: This is a zero-dep copy for the usertrust-verify
5
+ * package. Do NOT import from usertrust. Only uses Node built-ins.
6
+ *
7
+ * Provides:
8
+ * - verifyChain() — linear hash chain verification
9
+ * - Merkle tree building, inclusion proofs, consistency proofs
10
+ */
11
+ export interface ChainVerificationResult {
12
+ valid: boolean;
13
+ eventsVerified: number;
14
+ errors: string[];
15
+ latestHash: string;
16
+ verifiedAt: string;
17
+ }
18
+ export declare function verifyChain(logPath: string): ChainVerificationResult;
19
+ export interface MerkleSibling {
20
+ readonly hash: string;
21
+ readonly position: "left" | "right";
22
+ }
23
+ export interface MerkleInclusionProof {
24
+ readonly version: 1;
25
+ readonly leafHash: string;
26
+ readonly leafIndex: number;
27
+ readonly treeSize: number;
28
+ readonly root: string;
29
+ readonly siblings: readonly MerkleSibling[];
30
+ readonly segmentId: string;
31
+ }
32
+ export interface MerkleConsistencyProof {
33
+ readonly firstSize: number;
34
+ readonly secondSize: number;
35
+ readonly firstRoot: string;
36
+ readonly secondRoot: string;
37
+ readonly proof: readonly string[];
38
+ }
39
+ export declare function hashLeaf(data: string): string;
40
+ export declare function hashInternal(left: string, right: string): string;
41
+ export declare function buildMerkleTree(leaves: string[]): {
42
+ root: string | undefined;
43
+ layers: string[][];
44
+ };
45
+ export declare function generateInclusionProof(leafIndex: number, leaves: string[], segmentId: string): MerkleInclusionProof;
46
+ export declare function verifyInclusionProof(proof: MerkleInclusionProof, publishedRoot: string, publishedTreeSize: number): boolean;
47
+ export declare function generateConsistencyProof(firstSize: number, secondSize: number, leaves: string[]): MerkleConsistencyProof;
48
+ export declare function verifyConsistencyProof(proof: MerkleConsistencyProof): boolean;
49
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,MAAM,WAAW,uBAAuB;IACvC,KAAK,EAAE,OAAO,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACnB;AASD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,uBAAuB,CAuEpE;AAOD,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;CACpC;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IAC5C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAQhE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG;IAClD,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;CACnB,CAwBA;AAED,wBAAgB,sBAAsB,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EAAE,EAChB,SAAS,EAAE,MAAM,GACf,oBAAoB,CAiDtB;AAED,wBAAgB,oBAAoB,CACnC,KAAK,EAAE,oBAAoB,EAC3B,aAAa,EAAE,MAAM,EACrB,iBAAiB,EAAE,MAAM,GACvB,OAAO,CAoBT;AAiDD,wBAAgB,wBAAwB,CACvC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EAAE,GACd,sBAAsB,CAgCxB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAqB7E"}
package/dist/verify.js ADDED
@@ -0,0 +1,313 @@
1
+ /**
2
+ * Audit Chain Verifier + Merkle Proofs — Zero-dependency standalone
3
+ *
4
+ * INTENTIONAL DUPLICATION: This is a zero-dep copy for the usertrust-verify
5
+ * package. Do NOT import from usertrust. Only uses Node built-ins.
6
+ *
7
+ * Provides:
8
+ * - verifyChain() — linear hash chain verification
9
+ * - Merkle tree building, inclusion proofs, consistency proofs
10
+ */
11
+ import { createHash } from "node:crypto";
12
+ import { existsSync, readFileSync } from "node:fs";
13
+ import { canonicalize } from "./canonical.js";
14
+ import { GENESIS_HASH } from "./constants.js";
15
+ export function verifyChain(logPath) {
16
+ const errors = [];
17
+ if (!existsSync(logPath)) {
18
+ return {
19
+ valid: true,
20
+ eventsVerified: 0,
21
+ errors: [],
22
+ latestHash: GENESIS_HASH,
23
+ verifiedAt: new Date().toISOString(),
24
+ };
25
+ }
26
+ const content = readFileSync(logPath, "utf-8").trim();
27
+ if (!content) {
28
+ return {
29
+ valid: true,
30
+ eventsVerified: 0,
31
+ errors: [],
32
+ latestHash: GENESIS_HASH,
33
+ verifiedAt: new Date().toISOString(),
34
+ };
35
+ }
36
+ const lines = content.split("\n").filter((l) => l.trim());
37
+ let expectedPreviousHash = GENESIS_HASH;
38
+ let latestHash = GENESIS_HASH;
39
+ for (let i = 0; i < lines.length; i++) {
40
+ const line = lines[i];
41
+ let event;
42
+ try {
43
+ event = JSON.parse(line);
44
+ }
45
+ catch (parseErr) {
46
+ errors.push(`Event ${i + 1}: malformed JSON — ${parseErr instanceof Error ? parseErr.message : String(parseErr)}`);
47
+ expectedPreviousHash = "";
48
+ continue;
49
+ }
50
+ if (event.previousHash !== expectedPreviousHash) {
51
+ errors.push(`Event ${i + 1} (${event.id}): previousHash mismatch. ` +
52
+ `Expected ${expectedPreviousHash}, got ${event.previousHash}`);
53
+ }
54
+ const { hash: storedHash, ...eventWithoutHash } = event;
55
+ const canonical = canonicalize(eventWithoutHash);
56
+ const computedHash = createHash("sha256").update(canonical).digest("hex");
57
+ if (storedHash !== computedHash) {
58
+ errors.push(`Event ${i + 1} (${event.id}): hash mismatch. ` +
59
+ `Expected ${computedHash}, got ${storedHash}`);
60
+ }
61
+ expectedPreviousHash = storedHash;
62
+ latestHash = storedHash;
63
+ }
64
+ return {
65
+ valid: errors.length === 0,
66
+ eventsVerified: lines.length,
67
+ errors,
68
+ latestHash,
69
+ verifiedAt: new Date().toISOString(),
70
+ };
71
+ }
72
+ // ── Merkle Tree ──
73
+ const LEAF_PREFIX = Buffer.from([0x00]);
74
+ const INTERNAL_PREFIX = Buffer.from([0x01]);
75
+ export function hashLeaf(data) {
76
+ const dataBuffer = Buffer.from(data, "hex");
77
+ return createHash("sha256").update(LEAF_PREFIX).update(dataBuffer).digest("hex");
78
+ }
79
+ export function hashInternal(left, right) {
80
+ const leftBuffer = Buffer.from(left, "hex");
81
+ const rightBuffer = Buffer.from(right, "hex");
82
+ return createHash("sha256")
83
+ .update(INTERNAL_PREFIX)
84
+ .update(leftBuffer)
85
+ .update(rightBuffer)
86
+ .digest("hex");
87
+ }
88
+ export function buildMerkleTree(leaves) {
89
+ if (leaves.length === 0) {
90
+ return { root: undefined, layers: [[]] };
91
+ }
92
+ let currentLayer = leaves.map((leaf) => hashLeaf(leaf));
93
+ const layers = [currentLayer];
94
+ while (currentLayer.length > 1) {
95
+ const nextLayer = [];
96
+ for (let i = 0; i < currentLayer.length; i += 2) {
97
+ const left = currentLayer[i];
98
+ if (i + 1 < currentLayer.length) {
99
+ const right = currentLayer[i + 1];
100
+ nextLayer.push(hashInternal(left, right));
101
+ }
102
+ else {
103
+ nextLayer.push(left);
104
+ }
105
+ }
106
+ currentLayer = nextLayer;
107
+ layers.push(currentLayer);
108
+ }
109
+ return { root: currentLayer[0], layers };
110
+ }
111
+ export function generateInclusionProof(leafIndex, leaves, segmentId) {
112
+ if (leafIndex < 0 || leafIndex >= leaves.length) {
113
+ throw new RangeError(`leafIndex ${leafIndex} out of bounds for ${leaves.length} leaves`);
114
+ }
115
+ const { root, layers } = buildMerkleTree(leaves);
116
+ if (root === undefined) {
117
+ throw new Error("Cannot generate proof for empty tree");
118
+ }
119
+ const siblings = [];
120
+ let currentIndex = leafIndex;
121
+ for (let level = 0; level < layers.length - 1; level++) {
122
+ const layer = layers[level];
123
+ const layerSize = layer.length;
124
+ if (currentIndex === layerSize - 1 && layerSize % 2 === 1) {
125
+ currentIndex = Math.floor(currentIndex / 2);
126
+ continue;
127
+ }
128
+ if (currentIndex % 2 === 0) {
129
+ siblings.push({
130
+ hash: layer[currentIndex + 1],
131
+ position: "right",
132
+ });
133
+ }
134
+ else {
135
+ siblings.push({
136
+ hash: layer[currentIndex - 1],
137
+ position: "left",
138
+ });
139
+ }
140
+ currentIndex = Math.floor(currentIndex / 2);
141
+ }
142
+ const leafHash = leaves[leafIndex];
143
+ return {
144
+ version: 1,
145
+ leafHash,
146
+ leafIndex,
147
+ treeSize: leaves.length,
148
+ root,
149
+ segmentId,
150
+ siblings,
151
+ };
152
+ }
153
+ export function verifyInclusionProof(proof, publishedRoot, publishedTreeSize) {
154
+ if (proof.treeSize !== publishedTreeSize) {
155
+ return false;
156
+ }
157
+ if (proof.root !== publishedRoot) {
158
+ return false;
159
+ }
160
+ let currentHash = hashLeaf(proof.leafHash);
161
+ for (const sibling of proof.siblings) {
162
+ if (sibling.position === "left") {
163
+ currentHash = hashInternal(sibling.hash, currentHash);
164
+ }
165
+ else {
166
+ currentHash = hashInternal(currentHash, sibling.hash);
167
+ }
168
+ }
169
+ return currentHash === proof.root;
170
+ }
171
+ function largestPowerOf2LessThan(n) {
172
+ if (n <= 1)
173
+ return 0;
174
+ let k = 1;
175
+ while (k * 2 < n) {
176
+ k *= 2;
177
+ }
178
+ return k;
179
+ }
180
+ function isPowerOf2(n) {
181
+ return n > 0 && (n & (n - 1)) === 0;
182
+ }
183
+ function subproof(m, n, leaves, proof, startFromOld) {
184
+ if (m === n) {
185
+ if (!startFromOld) {
186
+ const { root } = buildMerkleTree(leaves.slice(0, n));
187
+ if (root !== undefined) {
188
+ proof.push(root);
189
+ }
190
+ }
191
+ return;
192
+ }
193
+ const k = largestPowerOf2LessThan(n);
194
+ if (m <= k) {
195
+ subproof(m, k, leaves, proof, startFromOld);
196
+ const { root } = buildMerkleTree(leaves.slice(k, n));
197
+ if (root !== undefined) {
198
+ proof.push(root);
199
+ }
200
+ }
201
+ else {
202
+ subproof(m - k, n - k, leaves.slice(k), proof, false);
203
+ const { root } = buildMerkleTree(leaves.slice(0, k));
204
+ if (root !== undefined) {
205
+ proof.push(root);
206
+ }
207
+ }
208
+ }
209
+ export function generateConsistencyProof(firstSize, secondSize, leaves) {
210
+ if (firstSize < 1 || firstSize > secondSize) {
211
+ throw new RangeError(`Invalid sizes: firstSize=${firstSize}, secondSize=${secondSize}`);
212
+ }
213
+ if (secondSize > leaves.length) {
214
+ throw new RangeError(`secondSize ${secondSize} exceeds available leaves ${leaves.length}`);
215
+ }
216
+ const firstTree = buildMerkleTree(leaves.slice(0, firstSize));
217
+ const secondTree = buildMerkleTree(leaves.slice(0, secondSize));
218
+ if (firstSize === secondSize) {
219
+ return {
220
+ firstSize,
221
+ secondSize,
222
+ firstRoot: firstTree.root,
223
+ secondRoot: secondTree.root,
224
+ proof: [],
225
+ };
226
+ }
227
+ const proof = [];
228
+ const secondLeaves = leaves.slice(0, secondSize);
229
+ subproof(firstSize, secondSize, secondLeaves, proof, true);
230
+ return {
231
+ firstSize,
232
+ secondSize,
233
+ firstRoot: firstTree.root,
234
+ secondRoot: secondTree.root,
235
+ proof,
236
+ };
237
+ }
238
+ export function verifyConsistencyProof(proof) {
239
+ if (proof.firstSize < 1 || proof.firstSize > proof.secondSize) {
240
+ return false;
241
+ }
242
+ if (proof.firstSize === proof.secondSize) {
243
+ return proof.proof.length === 0 && proof.firstRoot === proof.secondRoot;
244
+ }
245
+ if (proof.proof.length === 0) {
246
+ return false;
247
+ }
248
+ const { firstRoot, secondRoot } = recomputeRoots(proof.firstSize, proof.secondSize, proof.proof, proof.firstRoot);
249
+ return firstRoot === proof.firstRoot && secondRoot === proof.secondRoot;
250
+ }
251
+ function recomputeRoots(firstSize, secondSize, proofNodes, claimedFirstRoot) {
252
+ let idx = 0;
253
+ function consume() {
254
+ if (idx >= proofNodes.length)
255
+ return undefined;
256
+ return proofNodes[idx++];
257
+ }
258
+ const stack = [];
259
+ function collect(m, n, isOld) {
260
+ if (m === n) {
261
+ if (!isOld) {
262
+ const node = consume();
263
+ if (node !== undefined) {
264
+ stack.push({ hash: node, side: "both" });
265
+ }
266
+ }
267
+ return;
268
+ }
269
+ const k = largestPowerOf2LessThan(n);
270
+ if (m <= k) {
271
+ collect(m, k, isOld);
272
+ const node = consume();
273
+ if (node !== undefined) {
274
+ stack.push({ hash: node, side: "right" });
275
+ }
276
+ }
277
+ else {
278
+ collect(m - k, n - k, false);
279
+ const node = consume();
280
+ if (node !== undefined) {
281
+ stack.push({ hash: node, side: "left" });
282
+ }
283
+ }
284
+ }
285
+ collect(firstSize, secondSize, true);
286
+ if (stack.length === 0)
287
+ return { firstRoot: "", secondRoot: "" };
288
+ let fr;
289
+ let sr;
290
+ let startIdx;
291
+ if (isPowerOf2(firstSize)) {
292
+ fr = claimedFirstRoot;
293
+ sr = claimedFirstRoot;
294
+ startIdx = 0;
295
+ }
296
+ else {
297
+ fr = stack[0].hash;
298
+ sr = stack[0].hash;
299
+ startIdx = 1;
300
+ }
301
+ for (let i = startIdx; i < stack.length; i++) {
302
+ const entry = stack[i];
303
+ if (entry.side === "right") {
304
+ sr = hashInternal(sr, entry.hash);
305
+ }
306
+ else {
307
+ fr = hashInternal(entry.hash, fr);
308
+ sr = hashInternal(entry.hash, sr);
309
+ }
310
+ }
311
+ return { firstRoot: fr, secondRoot: sr };
312
+ }
313
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "usertrust-verify",
3
+ "version": "0.1.0",
4
+ "description": "Zero-dependency verifier for usertrust governance receipts. Validates hash chains, Merkle proofs, and audit trails.",
5
+ "license": "Apache-2.0",
6
+ "author": "Usertools, Inc. <hello@usertools.ai> (https://usertrust.ai)",
7
+ "homepage": "https://usertrust.ai",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/usertools-ai/usertrust.git",
11
+ "directory": "packages/verify"
12
+ },
13
+ "bugs": "https://github.com/usertools-ai/usertrust/issues",
14
+ "keywords": ["ai", "governance", "audit", "verify", "hash-chain", "merkle"],
15
+ "type": "module",
16
+ "main": "dist/index.js",
17
+ "types": "dist/index.d.ts",
18
+ "bin": { "verify": "./dist/bin/verify.js" },
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "prepublishOnly": "tsc"
22
+ },
23
+ "files": ["dist"],
24
+ "dependencies": {}
25
+ }