@nekzus/liop 2.4.0-alpha.21 → 2.4.0-alpha.23
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.
- package/README.md +72 -36
- package/dist/bin/agent.js +8 -7
- package/dist/bin/agent.js.map +1 -1
- package/dist/bridge.d.ts +4 -3
- package/dist/bridge.js +3 -2
- package/dist/{chunk-FCFTYOAS.js → chunk-3WKFZQ34.js} +22 -12
- package/dist/chunk-3WKFZQ34.js.map +1 -0
- package/dist/{chunk-VRB5HUYU.js → chunk-AMSFSS2I.js} +14 -9
- package/dist/chunk-AMSFSS2I.js.map +1 -0
- package/dist/{chunk-VRDZ5IKE.js → chunk-E2CFIWD6.js} +15 -9
- package/dist/chunk-E2CFIWD6.js.map +1 -0
- package/dist/{chunk-EJ426URA.js → chunk-E7RSX476.js} +4 -4
- package/dist/{chunk-EJ426URA.js.map → chunk-E7RSX476.js.map} +1 -1
- package/dist/{chunk-UJFWPRDM.js → chunk-GFGSHQN5.js} +3 -3
- package/dist/{chunk-UJFWPRDM.js.map → chunk-GFGSHQN5.js.map} +1 -1
- package/dist/{chunk-XRDN232O.js → chunk-KB3HUVMD.js} +2 -2
- package/dist/chunk-KB3HUVMD.js.map +1 -0
- package/dist/chunk-OHMZZMMC.js +58 -0
- package/dist/chunk-OHMZZMMC.js.map +1 -0
- package/dist/chunk-P34HDRN5.js +213 -0
- package/dist/chunk-P34HDRN5.js.map +1 -0
- package/dist/{chunk-PAICJCKJ.js → chunk-Q3FKHJ3B.js} +17 -4
- package/dist/chunk-Q3FKHJ3B.js.map +1 -0
- package/dist/{chunk-5SWHE62F.js → chunk-T2QDHVUD.js} +71 -11
- package/dist/chunk-T2QDHVUD.js.map +1 -0
- package/dist/{chunk-2KSO3W4A.js → chunk-YLFNJQI2.js} +2 -2
- package/dist/{chunk-2KSO3W4A.js.map → chunk-YLFNJQI2.js.map} +1 -1
- package/dist/{chunk-2STZHJ24.js → chunk-ZRWNMP5L.js} +58 -7
- package/dist/chunk-ZRWNMP5L.js.map +1 -0
- package/dist/client.d.ts +5 -4
- package/dist/client.js +7 -6
- package/dist/gateway.d.ts +6 -5
- package/dist/gateway.js +7 -6
- package/dist/{hybrid-DWe1bMoV.d.ts → hybrid-B7EjCj3q.d.ts} +4 -4
- package/dist/{index-CdW8j8Bn.d.ts → index-D2P6Z_hP.d.ts} +25 -2
- package/dist/{index-BuEQtBHD.d.ts → index-DDwiS7tf.d.ts} +8 -4
- package/dist/index.d.ts +51 -9
- package/dist/index.js +12 -10
- package/dist/index.js.map +1 -1
- package/dist/mesh.d.ts +1 -1
- package/dist/mesh.js +1 -1
- package/dist/{node-B0b2vUFS.d.ts → node-Djzm6UYd.d.ts} +8 -0
- package/dist/protocol/liop_core.proto +22 -6
- package/dist/server.d.ts +4 -3
- package/dist/server.js +5 -4
- package/dist/{types-CzRSOlOo.d.ts → types-rxL19f0l.d.ts} +3 -0
- package/dist/types.d.ts +2 -1
- package/dist/types.js +2 -1
- package/dist/{verifier-COnid_dg.d.ts → verifier-DTn1LXDU.d.ts} +25 -3
- package/dist/verifier-UBJTZQSA.js +6 -0
- package/dist/{verifier-XFU7ZB2W.js.map → verifier-UBJTZQSA.js.map} +1 -1
- package/dist/workers/logic-execution.d.ts +6 -0
- package/dist/workers/logic-execution.js +56 -1
- package/dist/workers/logic-execution.js.map +1 -1
- package/dist/workers/zk-verifier.d.ts +9 -0
- package/dist/workers/zk-verifier.js +119 -47
- package/dist/workers/zk-verifier.js.map +1 -1
- package/dist/zk-CYImPsa6.d.ts +91 -0
- package/package.json +2 -1
- package/dist/chunk-2STZHJ24.js.map +0 -1
- package/dist/chunk-5SWHE62F.js.map +0 -1
- package/dist/chunk-FCFTYOAS.js.map +0 -1
- package/dist/chunk-PAICJCKJ.js.map +0 -1
- package/dist/chunk-VRB5HUYU.js.map +0 -1
- package/dist/chunk-VRDZ5IKE.js.map +0 -1
- package/dist/chunk-XRDN232O.js.map +0 -1
- package/dist/verifier-XFU7ZB2W.js +0 -6
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { deserializeVKey, deserializeGrothProof, verifyGroth16Proof } from '../chunk-OHMZZMMC.js';
|
|
1
2
|
import { deriveLogicImageDigest } from '../chunk-IK7CGWAZ.js';
|
|
3
|
+
import { receiptCodec, RECEIPT_VERSION_V1, RECEIPT_VERSION_V2, decodeJournalV2 } from '../chunk-P34HDRN5.js';
|
|
2
4
|
import crypto from 'crypto';
|
|
3
5
|
import 'worker_threads';
|
|
4
6
|
|
|
@@ -70,9 +72,12 @@ async function verifyZkReceipt(payload) {
|
|
|
70
72
|
const {
|
|
71
73
|
logicPayload,
|
|
72
74
|
remoteImageIdHex,
|
|
75
|
+
guestImageIdHex,
|
|
73
76
|
zkReceipt,
|
|
74
77
|
sessionSecret,
|
|
75
|
-
|
|
78
|
+
vkeyRaw,
|
|
79
|
+
expectedOutput,
|
|
80
|
+
zkPolicy
|
|
76
81
|
} = payload;
|
|
77
82
|
if (!logicPayload || !remoteImageIdHex || !zkReceipt) {
|
|
78
83
|
return {
|
|
@@ -80,73 +85,140 @@ async function verifyZkReceipt(payload) {
|
|
|
80
85
|
message: "Missing required verification fields."
|
|
81
86
|
};
|
|
82
87
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
verified: false,
|
|
88
|
-
message: `Integrity Violation: Local (${localImageIdHex.slice(0, 8)}) != Remote (${remoteImageIdHex.slice(0, 8)})`
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
const receiptBuf = Buffer.from(zkReceipt);
|
|
92
|
-
if (receiptBuf.length < 35) {
|
|
93
|
-
return {
|
|
94
|
-
verified: false,
|
|
95
|
-
message: "Receipt too short for binary format."
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
const version = receiptBuf[0];
|
|
99
|
-
if (version !== 1) {
|
|
88
|
+
let decodedReceipt;
|
|
89
|
+
try {
|
|
90
|
+
decodedReceipt = receiptCodec.decode(Buffer.from(zkReceipt));
|
|
91
|
+
} catch (err) {
|
|
100
92
|
return {
|
|
101
93
|
verified: false,
|
|
102
|
-
message: `
|
|
94
|
+
message: `Receipt Decode Failed: ${err.message}`
|
|
103
95
|
};
|
|
104
96
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
97
|
+
if (decodedReceipt.version === RECEIPT_VERSION_V1) {
|
|
98
|
+
if (zkPolicy === "required") {
|
|
99
|
+
return {
|
|
100
|
+
verified: false,
|
|
101
|
+
message: "Policy Violation: Clearance Tier requires ZK proof (Groth16), but received legacy HMAC."
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const localImageId = deriveImageId(logicPayload);
|
|
105
|
+
const localImageIdHex = localImageId.toString("hex");
|
|
106
|
+
if (localImageIdHex !== remoteImageIdHex) {
|
|
107
|
+
return {
|
|
108
|
+
verified: false,
|
|
109
|
+
message: `Integrity Violation: Local (${localImageIdHex.slice(0, 8)}) != Remote (${remoteImageIdHex.slice(0, 8)})`
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
let journalData;
|
|
113
|
+
try {
|
|
114
|
+
journalData = JSON.parse(decodedReceipt.journal.toString());
|
|
115
|
+
if (journalData.image_id !== localImageIdHex) {
|
|
116
|
+
return {
|
|
117
|
+
verified: false,
|
|
118
|
+
message: `Journal ImageID mismatch: ${journalData.image_id.slice(0, 8)} != ${localImageIdHex.slice(0, 8)}`
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
} catch (_e) {
|
|
122
|
+
return { verified: false, message: "Failed to parse journal data." };
|
|
123
|
+
}
|
|
124
|
+
if (sessionSecret && sessionSecret.length > 0) {
|
|
125
|
+
const expectedSeal = crypto.createHmac("sha256", sessionSecret).update(decodedReceipt.journal).digest();
|
|
126
|
+
if (!crypto.timingSafeEqual(decodedReceipt.proof, expectedSeal)) {
|
|
127
|
+
return {
|
|
128
|
+
verified: false,
|
|
129
|
+
message: "Invalid seal: HMAC verification failed."
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (expectedOutput !== void 0) {
|
|
134
|
+
const proxyOutput = tryExtractProxyOutput(logicPayload);
|
|
135
|
+
const actualExpected = proxyOutput !== null ? proxyOutput : expectedOutput;
|
|
136
|
+
const expectedOutputStr = typeof actualExpected === "string" ? actualExpected : actualExpected === void 0 ? "undefined" : JSON.stringify(actualExpected);
|
|
137
|
+
const expectedOutputHash = crypto.createHash("sha256").update(expectedOutputStr).digest("hex");
|
|
138
|
+
if (journalData.output_hash !== expectedOutputHash) {
|
|
139
|
+
return {
|
|
140
|
+
verified: false,
|
|
141
|
+
message: `Output Hash Mismatch (Replay/Tamper attempt): Journal output_hash (${journalData.output_hash.slice(0, 8)}) != Calculated output_hash (${expectedOutputHash.slice(0, 8)})`
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
109
145
|
return {
|
|
110
|
-
verified:
|
|
111
|
-
message: "
|
|
146
|
+
verified: true,
|
|
147
|
+
message: "HMAC Commitment Verified: Integrity intact.",
|
|
148
|
+
proofType: "hmac"
|
|
112
149
|
};
|
|
113
150
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
journalData = JSON.parse(journal.toString());
|
|
117
|
-
if (journalData.image_id !== localImageIdHex) {
|
|
151
|
+
if (decodedReceipt.version === RECEIPT_VERSION_V2) {
|
|
152
|
+
if (decodedReceipt.proofType !== 2 /* GROTH16 */) {
|
|
118
153
|
return {
|
|
119
154
|
verified: false,
|
|
120
|
-
message: `
|
|
155
|
+
message: `Unsupported ZK proof type in v2 receipt: ${decodedReceipt.proofType}`
|
|
121
156
|
};
|
|
122
157
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const expectedSeal = crypto.createHmac("sha256", sessionSecret).update(journal).digest();
|
|
128
|
-
if (!crypto.timingSafeEqual(seal, expectedSeal)) {
|
|
158
|
+
let journalV2;
|
|
159
|
+
try {
|
|
160
|
+
journalV2 = decodeJournalV2(decodedReceipt.journal);
|
|
161
|
+
} catch (err) {
|
|
129
162
|
return {
|
|
130
163
|
verified: false,
|
|
131
|
-
message:
|
|
164
|
+
message: `Failed to decode ZkJournalV2: ${err.message}`
|
|
132
165
|
};
|
|
133
166
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
167
|
+
if (guestImageIdHex) {
|
|
168
|
+
const actualGuestId = journalV2.guestImageId.toString("hex");
|
|
169
|
+
if (actualGuestId !== guestImageIdHex) {
|
|
170
|
+
return {
|
|
171
|
+
verified: false,
|
|
172
|
+
message: `Guest ImageID Mismatch: Injected guest environment tampered (${actualGuestId.slice(0, 8)} != ${guestImageIdHex.slice(0, 8)}).`
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
const expectedLogicDigest = deriveImageId(logicPayload);
|
|
177
|
+
if (!journalV2.logicDigest.equals(expectedLogicDigest)) {
|
|
141
178
|
return {
|
|
142
179
|
verified: false,
|
|
143
|
-
message: `
|
|
180
|
+
message: `Logic Digest Mismatch: Remote origin executed unexpected logic (${journalV2.logicDigest.toString("hex").slice(0, 8)} != ${expectedLogicDigest.toString("hex").slice(0, 8)})`
|
|
144
181
|
};
|
|
145
182
|
}
|
|
183
|
+
if (vkeyRaw && vkeyRaw.length > 0) {
|
|
184
|
+
try {
|
|
185
|
+
const vkey = deserializeVKey(Buffer.from(vkeyRaw));
|
|
186
|
+
const proofWithSignals = deserializeGrothProof(decodedReceipt.proof);
|
|
187
|
+
const isMathValid = verifyGroth16Proof(vkey, proofWithSignals);
|
|
188
|
+
if (!isMathValid) {
|
|
189
|
+
return {
|
|
190
|
+
verified: false,
|
|
191
|
+
message: "Groth16 mathematical pairing verification failed: invalid proof."
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
} catch (err) {
|
|
195
|
+
return {
|
|
196
|
+
verified: false,
|
|
197
|
+
message: `Groth16 verification failed to execute: ${err.message}`
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (expectedOutput !== void 0) {
|
|
202
|
+
const proxyOutput = tryExtractProxyOutput(logicPayload);
|
|
203
|
+
const actualExpected = proxyOutput !== null ? proxyOutput : expectedOutput;
|
|
204
|
+
const expectedOutputStr = typeof actualExpected === "string" ? actualExpected : actualExpected === void 0 ? "undefined" : JSON.stringify(actualExpected);
|
|
205
|
+
const expectedOutputDigest = crypto.createHash("sha256").update(expectedOutputStr).digest();
|
|
206
|
+
if (!journalV2.outputDigest.equals(expectedOutputDigest)) {
|
|
207
|
+
return {
|
|
208
|
+
verified: false,
|
|
209
|
+
message: `Output Digest Mismatch (Replay/Tamper attempt): Journal (${journalV2.outputDigest.toString("hex").slice(0, 8)}) != Calculated (${expectedOutputDigest.toString("hex").slice(0, 8)})`
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
verified: true,
|
|
215
|
+
message: "Groth16 Zero-Knowledge Proof Mathematically Certified.",
|
|
216
|
+
proofType: "groth16"
|
|
217
|
+
};
|
|
146
218
|
}
|
|
147
219
|
return {
|
|
148
|
-
verified:
|
|
149
|
-
message:
|
|
220
|
+
verified: false,
|
|
221
|
+
message: `Unsupported receipt version: ${decodedReceipt.version}`
|
|
150
222
|
};
|
|
151
223
|
}
|
|
152
224
|
async function workerHandler(task) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/workers/zk-verifier.ts"],"names":[],"mappings":"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","file":"zk-verifier.js","sourcesContent":["// Copyright 2026 Nekzus Solutions and contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport crypto from \"node:crypto\";\nimport { parentPort } from \"node:worker_threads\";\nimport { deriveLogicImageDigest } from \"../crypto/logic-image-id.js\";\n\n// Ensure this worker is used via Piscina pool\nif (!parentPort) {\n\t// Not fatal in Piscina, but handled appropriately\n}\n\n/**\n * ZK Verification Payload Structure.\n * Modeled after RISC Zero & SP1 Receipt formats.\n */\nexport interface ZkVerificationPayload {\n\taction: \"verify_receipt\" | \"warmup\";\n\t/** Original logic payload (JS/WASM) sent by client */\n\tlogicPayload?: Uint8Array;\n\t/** Expected ImageID (SHA-256) of the execution state */\n\tremoteImageIdHex?: string;\n\t/** Cbor-encoded or raw buffer containing the execution Receipt (Journal + Seal) */\n\tzkReceipt?: Uint8Array;\n\t/** Kyber-derived session secret to verify HMAC signature */\n\tsessionSecret?: Uint8Array;\n\t/** The expected output value of the computation for anti-replay/tampering verification */\n\texpectedOutput?: unknown;\n}\n\nfunction deriveImageId(logicPayload: Uint8Array): Buffer {\n\treturn deriveLogicImageDigest(logicPayload);\n}\n\ninterface ZkJournal {\n\timage_id: string;\n\tdataset_hash: string;\n\toutput_hash: string;\n\tfuel: number;\n\tts: number;\n}\n\nfunction tryExtractProxyOutput(logicPayload: Uint8Array): unknown | null {\n\ttry {\n\t\tconst logicStr = Buffer.from(logicPayload).toString(\"utf-8\").trim();\n\t\tif (!logicStr.includes(\"__liop_proxy_tool\")) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst firstBraceIdx = logicStr.indexOf(\"{\");\n\t\tif (firstBraceIdx === -1) {\n\t\t\treturn null;\n\t\t}\n\n\t\tlet braceCount = 0;\n\t\tlet inDoubleQuote = false;\n\t\tlet inSingleQuote = false;\n\t\tlet inBacktick = false;\n\t\tlet escaped = false;\n\t\tlet lastBraceIdx = -1;\n\n\t\tfor (let i = firstBraceIdx; i < logicStr.length; i++) {\n\t\t\tconst char = logicStr[i];\n\n\t\t\tif (escaped) {\n\t\t\t\tescaped = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === \"\\\\\") {\n\t\t\t\tescaped = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === '\"' && !inSingleQuote && !inBacktick) {\n\t\t\t\tinDoubleQuote = !inDoubleQuote;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === \"'\" && !inDoubleQuote && !inBacktick) {\n\t\t\t\tinSingleQuote = !inSingleQuote;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === \"`\" && !inDoubleQuote && !inSingleQuote) {\n\t\t\t\tinBacktick = !inBacktick;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!inDoubleQuote && !inSingleQuote && !inBacktick) {\n\t\t\t\tif (char === \"{\") {\n\t\t\t\t\tbraceCount++;\n\t\t\t\t} else if (char === \"}\") {\n\t\t\t\t\tbraceCount--;\n\t\t\t\t\tif (braceCount === 0) {\n\t\t\t\t\t\tlastBraceIdx = i;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (lastBraceIdx !== -1) {\n\t\t\tconst jsonStr = logicStr.slice(firstBraceIdx, lastBraceIdx + 1);\n\t\t\tconst parsed = JSON.parse(jsonStr);\n\t\t\tif (parsed?.__liop_proxy_tool) {\n\t\t\t\treturn parsed;\n\t\t\t}\n\t\t}\n\t} catch (_e) {\n\t\t// Fallback\n\t}\n\treturn null;\n}\n\n/**\n * Simulates heavy ZK-Proof cryptographic verification.\n * In a real environment, this delegates to @risc0/verifier or SP1 FFI bindings.\n */\nasync function verifyZkReceipt(\n\tpayload: ZkVerificationPayload,\n): Promise<{ verified: boolean; message: string }> {\n\tconst {\n\t\tlogicPayload,\n\t\tremoteImageIdHex,\n\t\tzkReceipt,\n\t\tsessionSecret,\n\t\texpectedOutput,\n\t} = payload;\n\n\tif (!logicPayload || !remoteImageIdHex || !zkReceipt) {\n\t\treturn {\n\t\t\tverified: false,\n\t\t\tmessage: \"Missing required verification fields.\",\n\t\t};\n\t}\n\n\t// 1. Calculate local ImageID (Integrity Check)\n\tconst localImageId = deriveImageId(logicPayload);\n\tconst localImageIdHex = localImageId.toString(\"hex\");\n\n\tif (localImageIdHex !== remoteImageIdHex) {\n\t\treturn {\n\t\t\tverified: false,\n\t\t\tmessage: `Integrity Violation: Local (${localImageIdHex.slice(0, 8)}) != Remote (${remoteImageIdHex.slice(0, 8)})`,\n\t\t};\n\t}\n\n\t// 2. Structural Verification: Deserialize Binary Receipt\n\tconst receiptBuf = Buffer.from(zkReceipt);\n\tif (receiptBuf.length < 35) {\n\t\t// 1 version + 2 len + 32 seal minimum\n\t\treturn {\n\t\t\tverified: false,\n\t\t\tmessage: \"Receipt too short for binary format.\",\n\t\t};\n\t}\n\n\tconst version = receiptBuf[0];\n\tif (version !== 0x01) {\n\t\treturn {\n\t\t\tverified: false,\n\t\t\tmessage: `Unknown receipt version: ${version}`,\n\t\t};\n\t}\n\n\tconst journalLen = receiptBuf.readUInt16BE(1);\n\tconst journal = receiptBuf.subarray(3, 3 + journalLen);\n\tconst seal = receiptBuf.subarray(3 + journalLen);\n\n\tif (seal.length !== 32) {\n\t\treturn {\n\t\t\tverified: false,\n\t\t\tmessage: \"Invalid seal length (expected 32 bytes HMAC-SHA256).\",\n\t\t};\n\t}\n\n\t// 3. Parse journal and verify imageId\n\tlet journalData: ZkJournal;\n\ttry {\n\t\tjournalData = JSON.parse(journal.toString()) as ZkJournal;\n\t\tif (journalData.image_id !== localImageIdHex) {\n\t\t\treturn {\n\t\t\t\tverified: false,\n\t\t\t\tmessage: `Journal ImageID mismatch: ${journalData.image_id.slice(0, 8)} != ${localImageIdHex.slice(0, 8)}`,\n\t\t\t};\n\t\t}\n\t} catch (_e) {\n\t\treturn { verified: false, message: \"Failed to parse journal data.\" };\n\t}\n\n\t// 4. Mathematical Verification (HMAC-SHA256)\n\tif (sessionSecret && sessionSecret.length > 0) {\n\t\tconst expectedSeal = crypto\n\t\t\t.createHmac(\"sha256\", sessionSecret)\n\t\t\t.update(journal)\n\t\t\t.digest();\n\t\tif (!crypto.timingSafeEqual(seal, expectedSeal)) {\n\t\t\treturn {\n\t\t\t\tverified: false,\n\t\t\t\tmessage: \"Invalid seal: HMAC verification failed.\",\n\t\t\t};\n\t\t}\n\t}\n\n\t// 5. Output Hash Verification (Anti-Replay / Anti-Tampering)\n\tif (expectedOutput !== undefined) {\n\t\tconst proxyOutput = tryExtractProxyOutput(logicPayload);\n\t\tconst actualExpected = proxyOutput !== null ? proxyOutput : expectedOutput;\n\n\t\tconst expectedOutputStr =\n\t\t\ttypeof actualExpected === \"string\"\n\t\t\t\t? actualExpected\n\t\t\t\t: actualExpected === undefined\n\t\t\t\t\t? \"undefined\"\n\t\t\t\t\t: JSON.stringify(actualExpected);\n\t\tconst expectedOutputHash = crypto\n\t\t\t.createHash(\"sha256\")\n\t\t\t.update(expectedOutputStr)\n\t\t\t.digest(\"hex\");\n\n\t\tif (journalData.output_hash !== expectedOutputHash) {\n\t\t\treturn {\n\t\t\t\tverified: false,\n\t\t\t\tmessage: `Output Hash Mismatch (Replay/Tamper attempt): Journal output_hash (${journalData.output_hash.slice(0, 8)}) != Calculated output_hash (${expectedOutputHash.slice(0, 8)})`,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn {\n\t\tverified: true,\n\t\tmessage: \"HMAC Commitment Verified: Integrity intact.\",\n\t};\n}\n\n/**\n * Main worker entry point for Piscina.\n */\nexport default async function workerHandler(\n\ttask: ZkVerificationPayload,\n): Promise<{ verified: boolean; message: string }> {\n\ttry {\n\t\tif (task.action === \"warmup\") {\n\t\t\treturn {\n\t\t\t\tverified: true,\n\t\t\t\tmessage: \"warm\",\n\t\t\t};\n\t\t}\n\t\tif (task.action === \"verify_receipt\") {\n\t\t\treturn await verifyZkReceipt(task);\n\t\t}\n\t\tthrow new Error(\"Unknown action in ZkVerifier Worker.\");\n\t} catch (error) {\n\t\treturn {\n\t\t\tverified: false,\n\t\t\tmessage: `Verification Error: ${(error as Error).message}`,\n\t\t};\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/workers/zk-verifier.ts"],"names":[],"mappings":"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","file":"zk-verifier.js","sourcesContent":["import crypto from \"node:crypto\";\nimport { parentPort } from \"node:worker_threads\";\nimport {\n\tdeserializeGrothProof,\n\tdeserializeVKey,\n\tverifyGroth16Proof,\n} from \"../crypto/groth16-verifier.js\";\nimport { deriveLogicImageDigest } from \"../crypto/logic-image-id.js\";\nimport {\n\tdecodeJournalV2,\n\tProofType,\n\tRECEIPT_VERSION_V1,\n\tRECEIPT_VERSION_V2,\n\treceiptCodec,\n\ttype ZkPolicy,\n} from \"../security/zk.js\";\n\n// Ensure this worker is used via Piscina pool\nif (!parentPort) {\n\t// Not fatal in Piscina, but handled appropriately\n}\n\n/**\n * ZK Verification Payload Structure.\n * Modeled after RISC Zero & SP1 Receipt formats.\n */\nexport interface ZkVerificationPayload {\n\taction: \"verify_receipt\" | \"warmup\";\n\t/** Original logic payload (JS/WASM) sent by client */\n\tlogicPayload?: Uint8Array;\n\t/** Expected ImageID (SHA-256) of the execution state */\n\tremoteImageIdHex?: string;\n\t/** Expected Guest ImageID (SHA-256) of the zkVM interpreter */\n\tguestImageIdHex?: string;\n\t/** Cbor-encoded or raw buffer containing the execution Receipt (Journal + Seal) */\n\tzkReceipt?: Uint8Array;\n\t/** Kyber-derived session secret to verify HMAC signature */\n\tsessionSecret?: Uint8Array;\n\t/** Serialized VerificationKey buffer for Groth16 mathematical verification */\n\tvkeyRaw?: Uint8Array;\n\t/** The expected output value of the computation for anti-replay/tampering verification */\n\texpectedOutput?: unknown;\n\t/** Enforcement policy for clearance tiers */\n\tzkPolicy?: ZkPolicy;\n}\n\nfunction deriveImageId(logicPayload: Uint8Array): Buffer {\n\treturn deriveLogicImageDigest(logicPayload);\n}\n\ninterface ZkJournal {\n\timage_id: string;\n\tdataset_hash: string;\n\toutput_hash: string;\n\tfuel: number;\n\tts: number;\n}\n\nfunction tryExtractProxyOutput(logicPayload: Uint8Array): unknown | null {\n\ttry {\n\t\tconst logicStr = Buffer.from(logicPayload).toString(\"utf-8\").trim();\n\t\tif (!logicStr.includes(\"__liop_proxy_tool\")) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst firstBraceIdx = logicStr.indexOf(\"{\");\n\t\tif (firstBraceIdx === -1) {\n\t\t\treturn null;\n\t\t}\n\n\t\tlet braceCount = 0;\n\t\tlet inDoubleQuote = false;\n\t\tlet inSingleQuote = false;\n\t\tlet inBacktick = false;\n\t\tlet escaped = false;\n\t\tlet lastBraceIdx = -1;\n\n\t\tfor (let i = firstBraceIdx; i < logicStr.length; i++) {\n\t\t\tconst char = logicStr[i];\n\n\t\t\tif (escaped) {\n\t\t\t\tescaped = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === \"\\\\\") {\n\t\t\t\tescaped = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === '\"' && !inSingleQuote && !inBacktick) {\n\t\t\t\tinDoubleQuote = !inDoubleQuote;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === \"'\" && !inDoubleQuote && !inBacktick) {\n\t\t\t\tinSingleQuote = !inSingleQuote;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (char === \"`\" && !inDoubleQuote && !inSingleQuote) {\n\t\t\t\tinBacktick = !inBacktick;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!inDoubleQuote && !inSingleQuote && !inBacktick) {\n\t\t\t\tif (char === \"{\") {\n\t\t\t\t\tbraceCount++;\n\t\t\t\t} else if (char === \"}\") {\n\t\t\t\t\tbraceCount--;\n\t\t\t\t\tif (braceCount === 0) {\n\t\t\t\t\t\tlastBraceIdx = i;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (lastBraceIdx !== -1) {\n\t\t\tconst jsonStr = logicStr.slice(firstBraceIdx, lastBraceIdx + 1);\n\t\t\tconst parsed = JSON.parse(jsonStr);\n\t\t\tif (parsed?.__liop_proxy_tool) {\n\t\t\t\treturn parsed;\n\t\t\t}\n\t\t}\n\t} catch (_e) {\n\t\t// Fallback\n\t}\n\treturn null;\n}\n\n/**\n * Simulates heavy ZK-Proof cryptographic verification.\n * In a real environment, this delegates to @risc0/verifier or SP1 FFI bindings.\n */\nasync function verifyZkReceipt(\n\tpayload: ZkVerificationPayload,\n): Promise<{ verified: boolean; message: string; proofType?: string }> {\n\tconst {\n\t\tlogicPayload,\n\t\tremoteImageIdHex,\n\t\tguestImageIdHex,\n\t\tzkReceipt,\n\t\tsessionSecret,\n\t\tvkeyRaw,\n\t\texpectedOutput,\n\t\tzkPolicy,\n\t} = payload;\n\n\tif (!logicPayload || !remoteImageIdHex || !zkReceipt) {\n\t\treturn {\n\t\t\tverified: false,\n\t\t\tmessage: \"Missing required verification fields.\",\n\t\t};\n\t}\n\n\tlet decodedReceipt: ReturnType<typeof receiptCodec.decode>;\n\ttry {\n\t\tdecodedReceipt = receiptCodec.decode(Buffer.from(zkReceipt));\n\t} catch (err) {\n\t\treturn {\n\t\t\tverified: false,\n\t\t\tmessage: `Receipt Decode Failed: ${(err as Error).message}`,\n\t\t};\n\t}\n\n\t// 1. Version 1 (HMAC Legacy Receipt)\n\tif (decodedReceipt.version === RECEIPT_VERSION_V1) {\n\t\tif (zkPolicy === \"required\") {\n\t\t\treturn {\n\t\t\t\tverified: false,\n\t\t\t\tmessage:\n\t\t\t\t\t\"Policy Violation: Clearance Tier requires ZK proof (Groth16), but received legacy HMAC.\",\n\t\t\t};\n\t\t}\n\n\t\t// Calculate local ImageID (Integrity Check)\n\t\tconst localImageId = deriveImageId(logicPayload);\n\t\tconst localImageIdHex = localImageId.toString(\"hex\");\n\n\t\tif (localImageIdHex !== remoteImageIdHex) {\n\t\t\treturn {\n\t\t\t\tverified: false,\n\t\t\t\tmessage: `Integrity Violation: Local (${localImageIdHex.slice(0, 8)}) != Remote (${remoteImageIdHex.slice(0, 8)})`,\n\t\t\t};\n\t\t}\n\n\t\t// Parse journal and verify imageId\n\t\tlet journalData: ZkJournal;\n\t\ttry {\n\t\t\tjournalData = JSON.parse(decodedReceipt.journal.toString()) as ZkJournal;\n\t\t\tif (journalData.image_id !== localImageIdHex) {\n\t\t\t\treturn {\n\t\t\t\t\tverified: false,\n\t\t\t\t\tmessage: `Journal ImageID mismatch: ${journalData.image_id.slice(0, 8)} != ${localImageIdHex.slice(0, 8)}`,\n\t\t\t\t};\n\t\t\t}\n\t\t} catch (_e) {\n\t\t\treturn { verified: false, message: \"Failed to parse journal data.\" };\n\t\t}\n\n\t\t// Mathematical Verification (HMAC-SHA256)\n\t\tif (sessionSecret && sessionSecret.length > 0) {\n\t\t\tconst expectedSeal = crypto\n\t\t\t\t.createHmac(\"sha256\", sessionSecret)\n\t\t\t\t.update(decodedReceipt.journal)\n\t\t\t\t.digest();\n\t\t\tif (!crypto.timingSafeEqual(decodedReceipt.proof, expectedSeal)) {\n\t\t\t\treturn {\n\t\t\t\t\tverified: false,\n\t\t\t\t\tmessage: \"Invalid seal: HMAC verification failed.\",\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Output Hash Verification (Anti-Replay / Anti-Tampering)\n\t\tif (expectedOutput !== undefined) {\n\t\t\tconst proxyOutput = tryExtractProxyOutput(logicPayload);\n\t\t\tconst actualExpected =\n\t\t\t\tproxyOutput !== null ? proxyOutput : expectedOutput;\n\n\t\t\tconst expectedOutputStr =\n\t\t\t\ttypeof actualExpected === \"string\"\n\t\t\t\t\t? actualExpected\n\t\t\t\t\t: actualExpected === undefined\n\t\t\t\t\t\t? \"undefined\"\n\t\t\t\t\t\t: JSON.stringify(actualExpected);\n\t\t\tconst expectedOutputHash = crypto\n\t\t\t\t.createHash(\"sha256\")\n\t\t\t\t.update(expectedOutputStr)\n\t\t\t\t.digest(\"hex\");\n\n\t\t\tif (journalData.output_hash !== expectedOutputHash) {\n\t\t\t\treturn {\n\t\t\t\t\tverified: false,\n\t\t\t\t\tmessage: `Output Hash Mismatch (Replay/Tamper attempt): Journal output_hash (${journalData.output_hash.slice(0, 8)}) != Calculated output_hash (${expectedOutputHash.slice(0, 8)})`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tverified: true,\n\t\t\tmessage: \"HMAC Commitment Verified: Integrity intact.\",\n\t\t\tproofType: \"hmac\",\n\t\t};\n\t}\n\n\t// 2. Version 2 (Groth16 / ZK Binary Receipt)\n\tif (decodedReceipt.version === RECEIPT_VERSION_V2) {\n\t\tif (decodedReceipt.proofType !== ProofType.GROTH16) {\n\t\t\treturn {\n\t\t\t\tverified: false,\n\t\t\t\tmessage: `Unsupported ZK proof type in v2 receipt: ${decodedReceipt.proofType}`,\n\t\t\t};\n\t\t}\n\n\t\tlet journalV2: ReturnType<typeof decodeJournalV2>;\n\t\ttry {\n\t\t\tjournalV2 = decodeJournalV2(decodedReceipt.journal);\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tverified: false,\n\t\t\t\tmessage: `Failed to decode ZkJournalV2: ${(err as Error).message}`,\n\t\t\t};\n\t\t}\n\n\t\t// Verify Guest Image ID if expected\n\t\tif (guestImageIdHex) {\n\t\t\tconst actualGuestId = journalV2.guestImageId.toString(\"hex\");\n\t\t\tif (actualGuestId !== guestImageIdHex) {\n\t\t\t\treturn {\n\t\t\t\t\tverified: false,\n\t\t\t\t\tmessage: `Guest ImageID Mismatch: Injected guest environment tampered (${actualGuestId.slice(0, 8)} != ${guestImageIdHex.slice(0, 8)}).`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Verify Logic Digest (Ensures remote executed the exact user logic dispatched)\n\t\tconst expectedLogicDigest = deriveImageId(logicPayload);\n\t\tif (!journalV2.logicDigest.equals(expectedLogicDigest)) {\n\t\t\treturn {\n\t\t\t\tverified: false,\n\t\t\t\tmessage: `Logic Digest Mismatch: Remote origin executed unexpected logic (${journalV2.logicDigest.toString(\"hex\").slice(0, 8)} != ${expectedLogicDigest.toString(\"hex\").slice(0, 8)})`,\n\t\t\t};\n\t\t}\n\n\t\t// Mathematical Verification via Groth16 pairing check\n\t\tif (vkeyRaw && vkeyRaw.length > 0) {\n\t\t\ttry {\n\t\t\t\tconst vkey = deserializeVKey(Buffer.from(vkeyRaw));\n\t\t\t\tconst proofWithSignals = deserializeGrothProof(decodedReceipt.proof);\n\t\t\t\tconst isMathValid = verifyGroth16Proof(vkey, proofWithSignals);\n\n\t\t\t\tif (!isMathValid) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tverified: false,\n\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\"Groth16 mathematical pairing verification failed: invalid proof.\",\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\treturn {\n\t\t\t\t\tverified: false,\n\t\t\t\t\tmessage: `Groth16 verification failed to execute: ${(err as Error).message}`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\t// Output Digest Verification (Anti-Replay / Anti-Tampering)\n\t\tif (expectedOutput !== undefined) {\n\t\t\tconst proxyOutput = tryExtractProxyOutput(logicPayload);\n\t\t\tconst actualExpected =\n\t\t\t\tproxyOutput !== null ? proxyOutput : expectedOutput;\n\n\t\t\tconst expectedOutputStr =\n\t\t\t\ttypeof actualExpected === \"string\"\n\t\t\t\t\t? actualExpected\n\t\t\t\t\t: actualExpected === undefined\n\t\t\t\t\t\t? \"undefined\"\n\t\t\t\t\t\t: JSON.stringify(actualExpected);\n\t\t\tconst expectedOutputDigest = crypto\n\t\t\t\t.createHash(\"sha256\")\n\t\t\t\t.update(expectedOutputStr)\n\t\t\t\t.digest();\n\n\t\t\tif (!journalV2.outputDigest.equals(expectedOutputDigest)) {\n\t\t\t\treturn {\n\t\t\t\t\tverified: false,\n\t\t\t\t\tmessage: `Output Digest Mismatch (Replay/Tamper attempt): Journal (${journalV2.outputDigest.toString(\"hex\").slice(0, 8)}) != Calculated (${expectedOutputDigest.toString(\"hex\").slice(0, 8)})`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tverified: true,\n\t\t\tmessage: \"Groth16 Zero-Knowledge Proof Mathematically Certified.\",\n\t\t\tproofType: \"groth16\",\n\t\t};\n\t}\n\n\treturn {\n\t\tverified: false,\n\t\tmessage: `Unsupported receipt version: ${decodedReceipt.version}`,\n\t};\n}\n\n/**\n * Main worker entry point for Piscina.\n */\nexport default async function workerHandler(\n\ttask: ZkVerificationPayload,\n): Promise<{ verified: boolean; message: string; proofType?: string }> {\n\ttry {\n\t\tif (task.action === \"warmup\") {\n\t\t\treturn {\n\t\t\t\tverified: true,\n\t\t\t\tmessage: \"warm\",\n\t\t\t};\n\t\t}\n\t\tif (task.action === \"verify_receipt\") {\n\t\t\treturn await verifyZkReceipt(task);\n\t\t}\n\t\tthrow new Error(\"Unknown action in ZkVerifier Worker.\");\n\t} catch (error) {\n\t\treturn {\n\t\t\tverified: false,\n\t\t\tmessage: `Verification Error: ${(error as Error).message}`,\n\t\t};\n\t}\n}\n"]}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
declare enum ProofType {
|
|
2
|
+
HMAC_LEGACY = 0,
|
|
3
|
+
GROTH16 = 2
|
|
4
|
+
}
|
|
5
|
+
declare const RECEIPT_VERSION_V1 = 1;
|
|
6
|
+
declare const RECEIPT_VERSION_V2 = 2;
|
|
7
|
+
declare const ZK_JOURNAL_V2_SIZE = 144;
|
|
8
|
+
interface ZkJournalV2 {
|
|
9
|
+
/** Image ID (SHA-256) of the guest interpreter */
|
|
10
|
+
guestImageId: Buffer;
|
|
11
|
+
/** SHA-256 digest of injected logic */
|
|
12
|
+
logicDigest: Buffer;
|
|
13
|
+
/** SHA-256 digest of dataset records */
|
|
14
|
+
datasetDigest: Buffer;
|
|
15
|
+
/** SHA-256 digest of sanitized output */
|
|
16
|
+
outputDigest: Buffer;
|
|
17
|
+
/** Micro-instruction fuel consumed */
|
|
18
|
+
fuelConsumed: bigint;
|
|
19
|
+
/** Timestamp in milliseconds since unix epoch */
|
|
20
|
+
executionTimestamp: bigint;
|
|
21
|
+
}
|
|
22
|
+
type ZkPolicy = "none" | "optimistic" | "required";
|
|
23
|
+
interface ZkReceipt {
|
|
24
|
+
/** Cryptographic proof generated by a zero-knowledge VM (e.g., RISC Zero, SP1) or Groth16 */
|
|
25
|
+
proof: Buffer;
|
|
26
|
+
/** The public inputs/outputs of the execution (the "Journal" in RISC Zero terminology) */
|
|
27
|
+
journal: Buffer;
|
|
28
|
+
/** The expected image ID / verification key of the WASM binary that was executed */
|
|
29
|
+
imageId: Buffer;
|
|
30
|
+
/** Type of cryptographic proof (HMAC legacy or Groth16) */
|
|
31
|
+
proofType?: ProofType;
|
|
32
|
+
/** Binary receipt version (0x01 or 0x02) */
|
|
33
|
+
version?: number;
|
|
34
|
+
}
|
|
35
|
+
declare class ZkVerificationError extends Error {
|
|
36
|
+
constructor(message: string);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Serializes a structured ZkJournalV2 into a strictly validated 144-byte binary layout.
|
|
40
|
+
*/
|
|
41
|
+
declare function encodeJournalV2(fields: ZkJournalV2): Buffer;
|
|
42
|
+
/**
|
|
43
|
+
* Deserializes and validates a 144-byte binary buffer into a typed ZkJournalV2.
|
|
44
|
+
*/
|
|
45
|
+
declare function decodeJournalV2(buf: Buffer): ZkJournalV2;
|
|
46
|
+
interface DecodedReceipt {
|
|
47
|
+
version: number;
|
|
48
|
+
proofType: ProofType;
|
|
49
|
+
journal: Buffer;
|
|
50
|
+
proof: Buffer;
|
|
51
|
+
raw: Buffer;
|
|
52
|
+
}
|
|
53
|
+
declare const receiptCodec: {
|
|
54
|
+
/**
|
|
55
|
+
* Encodes a version 2 Binary Receipt with trailing SHA-256 checksum.
|
|
56
|
+
* Layout: [0x02][proofType: 1B][journalLen: 4B UInt32BE][journal][proof][checksum: 32B]
|
|
57
|
+
*/
|
|
58
|
+
encodeV2(proofType: ProofType, journal: Buffer, proof: Buffer): Buffer;
|
|
59
|
+
/**
|
|
60
|
+
* Decodes any LIOP Binary Receipt (v1 HMAC or v2 ZK).
|
|
61
|
+
*/
|
|
62
|
+
decode(raw: Buffer): DecodedReceipt;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* ZK-Proofs Verifier for Logic-Injection-on-Origin Protocol (LIOP)
|
|
66
|
+
*
|
|
67
|
+
* Validates that an executed Logic (WASM) actually produced the reported output,
|
|
68
|
+
* verifying the Zero-Knowledge receipt generated by the remote host's Trusted Execution
|
|
69
|
+
* Environment (TEE) or zkVM (Zero-Knowledge Virtual Machine).
|
|
70
|
+
*/
|
|
71
|
+
declare const ZkVerifier: {
|
|
72
|
+
/**
|
|
73
|
+
* Validates a ZK receipt using structural Binary Receipt verification.
|
|
74
|
+
* Parses the HMAC-SHA256 commitment format (v1) and verifies journal integrity.
|
|
75
|
+
*
|
|
76
|
+
* @param receipt - Complete ZkReceipt to verify
|
|
77
|
+
* @param expectedImageId - Hash or ImageID of the WASM file dispatched to the host
|
|
78
|
+
* @throws ZkVerificationError if the proof is invalid or image IDs mismatch
|
|
79
|
+
* @returns true if the proof mathematically verifies the execution
|
|
80
|
+
*/
|
|
81
|
+
verify(receipt: ZkReceipt, expectedImageId: Buffer, sessionSecret?: Buffer): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Derives a predictable ImageID (usually a Hash) from a raw WASM binary.
|
|
84
|
+
*
|
|
85
|
+
* @param wasmBytes - The raw bytes of the WASM logic file
|
|
86
|
+
* @returns The SHA-256 ImageID of the logic
|
|
87
|
+
*/
|
|
88
|
+
deriveImageId(wasmBytes: Buffer): Buffer;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export { type DecodedReceipt as D, ProofType as P, RECEIPT_VERSION_V1 as R, type ZkPolicy as Z, RECEIPT_VERSION_V2 as a, ZK_JOURNAL_V2_SIZE as b, type ZkJournalV2 as c, type ZkReceipt as d, ZkVerificationError as e, ZkVerifier as f, decodeJournalV2 as g, encodeJournalV2 as h, receiptCodec as r };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nekzus/liop",
|
|
3
|
-
"version": "2.4.0-alpha.
|
|
3
|
+
"version": "2.4.0-alpha.23",
|
|
4
4
|
"description": "Official SDK for Logic-Injection-on-Origin Protocol (LIOP). Deploy Logic-on-Origin with WebAssembly at gRPC speed and bidirectional MCP compatibility.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -125,6 +125,7 @@
|
|
|
125
125
|
"it-pipe": "3.0.1",
|
|
126
126
|
"jose": "6.2.12",
|
|
127
127
|
"libp2p": "3.3.11",
|
|
128
|
+
"micro-zk-proofs": "0.3.1",
|
|
128
129
|
"mlkem": "2.7.0",
|
|
129
130
|
"multiformats": "14.0.5",
|
|
130
131
|
"oidc-provider": "9.12.2",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/crypto/verifier.ts"],"names":["__filename","__dirname"],"mappings":"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","file":"chunk-2STZHJ24.js","sourcesContent":["// Copyright 2026 Nekzus Solutions and contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport * as fs from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { Piscina } from \"piscina\";\nimport { zkVerificationDurationMs } from \"../observability/metrics.js\";\nimport { log } from \"../utils/logger.js\";\nimport { deriveLogicImageDigest } from \"./logic-image-id.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * LIOP Tier-0 Industrial Verifier\n *\n * This engine is responsible for the trustless verification of remote logic execution.\n * It validates both the integrity of the code (ZkImageID) and the mathematical proof\n * of its execution (ZkSeal), as well as hardware-level attestation (TEE).\n */\nexport class LiopVerifier {\n\t// Singleton Worker Pool for heavy ZK verification\n\tprivate static zkWorkerPool: Piscina | null = null;\n\n\tprivate getZkPool() {\n\t\tif (!LiopVerifier.zkWorkerPool) {\n\t\t\tconst isTS = import.meta.url.endsWith(\".ts\");\n\t\t\tconst workerExt = isTS ? \".ts\" : \".js\";\n\n\t\t\tlet execArgv: string[] = [];\n\t\t\tif (isTS) {\n\t\t\t\ttry {\n\t\t\t\t\tconst req = createRequire(import.meta.url);\n\t\t\t\t\tconst tsxPkg = req.resolve(\"tsx/package.json\");\n\t\t\t\t\tconst absoluteTsx = pathToFileURL(\n\t\t\t\t\t\tpath.join(path.dirname(tsxPkg), \"dist\", \"loader.mjs\"),\n\t\t\t\t\t).href;\n\t\t\t\t\texecArgv = [\"--import\", absoluteTsx];\n\t\t\t\t} catch (_e) {\n\t\t\t\t\texecArgv = [\"--import\", \"tsx\"];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Support both flat dist/ and original src/ structure\n\t\t\tconst workerPaths = [\n\t\t\t\tpath.resolve(__dirname, `./workers/zk-verifier${workerExt}`), // Flat dist/ (tsup)\n\t\t\t\tpath.resolve(__dirname, `../workers/zk-verifier${workerExt}`), // Original src/\n\t\t\t];\n\n\t\t\tconst workerFilename =\n\t\t\t\tworkerPaths.find((p) => fs.existsSync(p)) || workerPaths[1];\n\n\t\t\tLiopVerifier.zkWorkerPool = new Piscina({\n\t\t\t\tfilename: workerFilename,\n\t\t\t\tminThreads: 1,\n\t\t\t\tmaxThreads: 2, // Minimal footprint since verification is fast compared to generation\n\t\t\t\tidleTimeout: 30000,\n\t\t\t\texecArgv,\n\t\t\t});\n\n\t\t\t// Pre-warm the verification worker\n\t\t\tLiopVerifier.zkWorkerPool.run({ action: \"warmup\" }).catch((err) => {\n\t\t\t\tlog.debug(\n\t\t\t\t\t`[LiopVerifier] Verification pool warm-up ping failed: ${err.message}`,\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t\treturn LiopVerifier.zkWorkerPool;\n\t}\n\n\t/**\n\t * Verifies a Zero-Knowledge Receipt from a remote LIOP node via Worker Pool.\n\t *\n\t * @param logicPayload The raw WASM or JS logic that was sent to the provider.\n\t * @param remoteImageIdHex The ImageID reported by the provider (must match our local calculation).\n\t * @param zkReceipt The mathematical proof (Seal + Journal) from the zkVM.\n\t */\n\tpublic async verifyZkReceipt(\n\t\tlogicPayload: Buffer,\n\t\tremoteImageIdHex: string,\n\t\tzkReceipt: Buffer,\n\t\tsessionSecret?: Buffer,\n\t\texpectedOutput?: unknown,\n\t): Promise<boolean> {\n\t\tconst pool = this.getZkPool();\n\t\tif (!pool) throw new Error(\"Worker pool initialization failed\");\n\t\tconst startTime = performance.now();\n\t\tconst result = await pool.run({\n\t\t\taction: \"verify_receipt\",\n\t\t\tlogicPayload: new Uint8Array(logicPayload),\n\t\t\tremoteImageIdHex,\n\t\t\tzkReceipt: new Uint8Array(zkReceipt),\n\t\t\tsessionSecret: sessionSecret ? new Uint8Array(sessionSecret) : undefined,\n\t\t\texpectedOutput,\n\t\t});\n\t\tconst durationMs = performance.now() - startTime;\n\n\t\ttry {\n\t\t\tzkVerificationDurationMs.observe(\n\t\t\t\t{ status: result.verified ? \"verified\" : \"failed\" },\n\t\t\t\tdurationMs,\n\t\t\t);\n\t\t} catch {\n\t\t\t// Metrics observation failure must never disrupt cryptographic verification\n\t\t}\n\n\t\tif (result.verified) {\n\t\t\tlog.info(`[LiopVerifier] ${result.message}`);\n\t\t\treturn true;\n\t\t}\n\n\t\tlog.error(`[LiopVerifier] FAILED: ${result.message}`);\n\t\treturn false;\n\t}\n\n\t/**\n\t * Verifies if a node is running inside an authenticated TEE (e.g. AWS Nitro).\n\t *\n\t * @param attestationReport The COSE-signed attestation document from the hardware.\n\t */\n\tpublic async verifyTeeAttestation(\n\t\tattestationReport: Buffer,\n\t): Promise<boolean> {\n\t\tif (attestationReport.length === 0) return true; // Optional in Mesh Alpha\n\n\t\ttry {\n\t\t\t// Architecture for AWS Nitro Enclaves:\n\t\t\t// 1. Decode CBOR/COSE\n\t\t\t// 2. Verify Signature against AWS Nitro Root CA\n\t\t\t// 3. Compare PCRs\n\t\t\tlog.info(\"[LiopVerifier] TEE Attestation: Not configured (no-op).\");\n\t\t\treturn true;\n\t\t} catch (err) {\n\t\t\tlog.error(\"[LiopVerifier] TEE Verification Failed:\", err);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * Derives the ImageID of a logic payload following the LIOP v1 Standard.\n\t */\n\tpublic deriveImageId(logicPayload: Buffer): Buffer {\n\t\treturn deriveLogicImageDigest(logicPayload);\n\t}\n}\n"]}
|