@nekzus/liop 2.5.0-beta.1 → 2.5.0-beta.3
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/NOTICE +19 -0
- package/README.md +148 -69
- package/dist/bin/agent.js +27 -303
- package/dist/bridge.d.ts +4 -3
- package/dist/bridge.js +1 -4
- package/dist/chunk-2XHSALII.js +3 -0
- package/dist/chunk-2ZYX736J.js +2 -0
- package/dist/chunk-3WRKTVOF.js +2 -0
- package/dist/chunk-6KFKO6ZX.js +2 -0
- package/dist/chunk-6VK2XALI.js +2 -0
- package/dist/chunk-AYDF3IFZ.js +2 -0
- package/dist/chunk-CTTTLCGL.js +31 -0
- package/dist/chunk-ECRS6N33.js +4 -0
- package/dist/chunk-FDJMH4CB.js +2 -0
- package/dist/chunk-FTF6AMF6.js +2 -0
- package/dist/chunk-GWVSCZUS.js +2 -0
- package/dist/chunk-LEXMMIQI.js +15 -0
- package/dist/chunk-LM26HOJ6.js +31 -0
- package/dist/chunk-MQ5SU26J.js +2 -0
- package/dist/chunk-N35BC62H.js +2 -0
- package/dist/chunk-P6IJ3VBD.js +3 -0
- package/dist/chunk-TKLRW52V.js +2 -0
- package/dist/chunk-V35CXJQN.js +2 -0
- package/dist/chunk-WP5ER7RH.js +3 -0
- package/dist/chunk-XLVEDKM6.js +2 -0
- package/dist/chunk-Y675R34Z.js +2 -0
- package/dist/chunk-YD2AF2M6.js +46 -0
- package/dist/chunk-YLCNV764.js +3 -0
- package/dist/chunk-ZZMSFCJP.js +3 -0
- package/dist/client.d.ts +6 -4
- package/dist/client.js +1 -9
- package/dist/gateway.d.ts +6 -5
- package/dist/gateway.js +1 -10
- package/dist/{hybrid-CF__0YnC.d.ts → hybrid-BZpCiUaV.d.ts} +6 -5
- package/dist/{index-cMV0_yD9.d.ts → index-BYDtRGue.d.ts} +45 -36
- package/dist/{index-BW95kAL4.d.ts → index-ByzjpRCk.d.ts} +37 -72
- package/dist/index.d.ts +221 -50
- package/dist/index.js +4 -312
- package/dist/kyber-PULV7PQX.js +2 -0
- package/dist/mesh.d.ts +27 -143
- package/dist/mesh.js +1 -4
- package/dist/node-Djzm6UYd.d.ts +172 -0
- package/dist/protocol/liop_core.proto +25 -6
- package/dist/server.d.ts +4 -3
- package/dist/server.js +1 -7
- package/dist/types-29zv9X1V.d.ts +455 -0
- package/dist/types.d.ts +2 -1
- package/dist/types.js +1 -2
- package/dist/verifier-DqZ9MQ9l.d.ts +82 -0
- package/dist/verifier-J4NQYZX5.js +2 -0
- package/dist/workers/logic-execution.d.ts +7 -0
- package/dist/workers/logic-execution.js +1 -271
- package/dist/workers/zk-verifier.d.ts +9 -0
- package/dist/workers/zk-verifier.js +1 -173
- package/dist/zk-DzYNWBgo.d.ts +104 -0
- package/package.json +56 -45
- package/dist/bin/agent.js.map +0 -1
- package/dist/bridge.js.map +0 -1
- package/dist/chunk-32ADSAJS.js +0 -104
- package/dist/chunk-32ADSAJS.js.map +0 -1
- package/dist/chunk-547TYL27.js +0 -208109
- package/dist/chunk-547TYL27.js.map +0 -1
- package/dist/chunk-72MNYFR6.js +0 -64
- package/dist/chunk-72MNYFR6.js.map +0 -1
- package/dist/chunk-74CISO2I.js +0 -853
- package/dist/chunk-74CISO2I.js.map +0 -1
- package/dist/chunk-CRZBVFDV.js +0 -616
- package/dist/chunk-CRZBVFDV.js.map +0 -1
- package/dist/chunk-GA3Q2S7O.js +0 -558
- package/dist/chunk-GA3Q2S7O.js.map +0 -1
- package/dist/chunk-JIJPZFR2.js +0 -51
- package/dist/chunk-JIJPZFR2.js.map +0 -1
- package/dist/chunk-OUUTDSOW.js +0 -24
- package/dist/chunk-OUUTDSOW.js.map +0 -1
- package/dist/chunk-PYKRQAER.js +0 -77
- package/dist/chunk-PYKRQAER.js.map +0 -1
- package/dist/chunk-QLCOEP5J.js +0 -68
- package/dist/chunk-QLCOEP5J.js.map +0 -1
- package/dist/chunk-RWRRBYG4.js +0 -3
- package/dist/chunk-RWRRBYG4.js.map +0 -1
- package/dist/chunk-SONUORBT.js +0 -421
- package/dist/chunk-SONUORBT.js.map +0 -1
- package/dist/chunk-T5IUZF47.js +0 -716
- package/dist/chunk-T5IUZF47.js.map +0 -1
- package/dist/chunk-U5BZ66VX.js +0 -447
- package/dist/chunk-U5BZ66VX.js.map +0 -1
- package/dist/chunk-WCCGE4QR.js +0 -3520
- package/dist/chunk-WCCGE4QR.js.map +0 -1
- package/dist/chunk-WSW6YJNY.js +0 -168
- package/dist/chunk-WSW6YJNY.js.map +0 -1
- package/dist/client.js.map +0 -1
- package/dist/gateway.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/kyber-3ULIJSE3.js +0 -3
- package/dist/kyber-3ULIJSE3.js.map +0 -1
- package/dist/mesh.js.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/types-lJIxBlWF.d.ts +0 -256
- package/dist/types.js.map +0 -1
- package/dist/verifier-3FAKCFNN.js +0 -5
- package/dist/verifier-3FAKCFNN.js.map +0 -1
- package/dist/verifier-COnid_dg.d.ts +0 -31
- package/dist/workers/logic-execution.js.map +0 -1
- package/dist/workers/zk-verifier.js.map +0 -1
|
@@ -1,272 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { sanitizeOutput } from '../chunk-JIJPZFR2.js';
|
|
3
|
-
import { normalizeLogicSource, deriveLogicImageDigest } from '../chunk-OUUTDSOW.js';
|
|
4
|
-
import { Buffer } from 'buffer';
|
|
5
|
-
import crypto2 from 'crypto';
|
|
6
|
-
import { createMlKem768 } from 'mlkem';
|
|
7
|
-
|
|
8
|
-
var DEFAULT_DP_CONFIG = {
|
|
9
|
-
epsilon: 1,
|
|
10
|
-
sensitivity: 1,
|
|
11
|
-
smallDatasetThreshold: 50
|
|
12
|
-
};
|
|
13
|
-
var EPSILON_FLOOR = 1;
|
|
14
|
-
var EPSILON_FLOOR_THRESHOLD = 10;
|
|
15
|
-
function laplaceSample(scale, prngState) {
|
|
16
|
-
let u;
|
|
17
|
-
do {
|
|
18
|
-
if (prngState) {
|
|
19
|
-
const hash = crypto2.createHash("sha256").update(`${prngState.seed}:${prngState.counter++}`).digest();
|
|
20
|
-
u = hash.readUInt32BE(0) / 4294967296 - 0.5;
|
|
21
|
-
} else {
|
|
22
|
-
const buf = crypto2.randomBytes(4);
|
|
23
|
-
const rawVal = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
|
|
24
|
-
const cleanVal = Number.parseInt(rawVal.toString(10), 10);
|
|
25
|
-
u = cleanVal / 4294967296;
|
|
26
|
-
}
|
|
27
|
-
} while (u === 0 || u === -0.5);
|
|
28
|
-
return -scale * Math.sign(u) * Math.log(1 - 2 * Math.abs(u));
|
|
29
|
-
}
|
|
30
|
-
function addLaplaceNoise(value, config = {}, prngState) {
|
|
31
|
-
const merged = { ...DEFAULT_DP_CONFIG, ...config };
|
|
32
|
-
const scale = merged.sensitivity / merged.epsilon;
|
|
33
|
-
const noisyValue = value + laplaceSample(scale, prngState);
|
|
34
|
-
return Math.round(noisyValue * 1e4) / 1e4;
|
|
35
|
-
}
|
|
36
|
-
function deriveFieldSensitivity(key, globalSensitivity, recordCount) {
|
|
37
|
-
if (!key) return globalSensitivity;
|
|
38
|
-
const lk = key.toLowerCase();
|
|
39
|
-
const isCountWord = /count|length|size|num|gainer|loser|positive|negative|nan_|null_|empty_|finite_|non_finite_|instruments|tickers|users|records/i.test(
|
|
40
|
-
lk
|
|
41
|
-
);
|
|
42
|
-
const isTotalCount = lk === "total" || lk === "n" || lk === "total_records" || lk.startsWith("total_") || // Catch total_tickers, total_users
|
|
43
|
-
lk.startsWith("num_") || // Catch num_records, num_ticks
|
|
44
|
-
/total.*(count|items|entries|rows|records|tickers)/i.test(lk);
|
|
45
|
-
if (isCountWord || isTotalCount) return 1;
|
|
46
|
-
if (/avg|mean|average|var|variance|std|stddev|ratio|bps|drift|pct|percent|imbalance/i.test(
|
|
47
|
-
lk
|
|
48
|
-
) && recordCount > 0) {
|
|
49
|
-
return globalSensitivity / recordCount;
|
|
50
|
-
}
|
|
51
|
-
return globalSensitivity;
|
|
52
|
-
}
|
|
53
|
-
function applyDpToOutput(output, config = {}, recordCount) {
|
|
54
|
-
const merged = { ...DEFAULT_DP_CONFIG, ...config };
|
|
55
|
-
if (recordCount >= merged.smallDatasetThreshold) {
|
|
56
|
-
return output;
|
|
57
|
-
}
|
|
58
|
-
if (recordCount < EPSILON_FLOOR_THRESHOLD && merged.epsilon < EPSILON_FLOOR) {
|
|
59
|
-
merged.epsilon = EPSILON_FLOOR;
|
|
60
|
-
}
|
|
61
|
-
let prngState;
|
|
62
|
-
if (merged.seed) {
|
|
63
|
-
prngState = { seed: merged.seed, counter: 0 };
|
|
64
|
-
}
|
|
65
|
-
return walkAndNoise(output, merged, recordCount, void 0, prngState);
|
|
66
|
-
}
|
|
67
|
-
function walkAndNoise(node, config, recordCount, currentKey, prngState) {
|
|
68
|
-
if (typeof node === "number" && Number.isFinite(node)) {
|
|
69
|
-
const fieldSensitivity = deriveFieldSensitivity(
|
|
70
|
-
currentKey,
|
|
71
|
-
config.sensitivity,
|
|
72
|
-
recordCount
|
|
73
|
-
);
|
|
74
|
-
let noisyValue = addLaplaceNoise(
|
|
75
|
-
node,
|
|
76
|
-
{
|
|
77
|
-
...config,
|
|
78
|
-
sensitivity: fieldSensitivity
|
|
79
|
-
},
|
|
80
|
-
prngState
|
|
81
|
-
);
|
|
82
|
-
const isCountKey = currentKey != null && deriveFieldSensitivity(currentKey, config.sensitivity, recordCount) === 1;
|
|
83
|
-
if (Number.isInteger(node) || isCountKey) {
|
|
84
|
-
noisyValue = Math.round(noisyValue);
|
|
85
|
-
}
|
|
86
|
-
if (node >= 0) {
|
|
87
|
-
noisyValue = Math.max(0, noisyValue);
|
|
88
|
-
}
|
|
89
|
-
return noisyValue;
|
|
90
|
-
}
|
|
91
|
-
if (Array.isArray(node)) {
|
|
92
|
-
return node.map(
|
|
93
|
-
(item) => walkAndNoise(item, config, recordCount, currentKey, prngState)
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
if (node !== null && typeof node === "object") {
|
|
97
|
-
const result = {};
|
|
98
|
-
for (const [key, value] of Object.entries(
|
|
99
|
-
node
|
|
100
|
-
)) {
|
|
101
|
-
result[key] = walkAndNoise(value, config, recordCount, key, prngState);
|
|
102
|
-
}
|
|
103
|
-
return result;
|
|
104
|
-
}
|
|
105
|
-
return node;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// src/workers/logic-execution.ts
|
|
109
|
-
async function processLogicExecution(data) {
|
|
110
|
-
if (typeof Object.prototype === "object" && !Object.isFrozen(Object.prototype)) {
|
|
111
|
-
Object.freeze(Object.prototype);
|
|
112
|
-
Object.freeze(Array.prototype);
|
|
113
|
-
Object.freeze(String.prototype);
|
|
114
|
-
Object.freeze(Number.prototype);
|
|
115
|
-
Object.freeze(Boolean.prototype);
|
|
116
|
-
Object.freeze(RegExp.prototype);
|
|
117
|
-
Object.freeze(Map.prototype);
|
|
118
|
-
Object.freeze(Set.prototype);
|
|
119
|
-
Object.freeze(Promise.prototype);
|
|
120
|
-
Object.freeze(Error.prototype);
|
|
121
|
-
}
|
|
122
|
-
if (data.isWarmup) {
|
|
123
|
-
return {
|
|
124
|
-
image_id: "",
|
|
125
|
-
output: "warm",
|
|
126
|
-
fuel_consumed: 0
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
if (data.sessionTimestamp !== void 0) {
|
|
130
|
-
const MAX_SESSION_KEY_LIFETIME_MS = 3600 * 1e3;
|
|
131
|
-
const age = Date.now() - data.sessionTimestamp;
|
|
132
|
-
if (age > MAX_SESSION_KEY_LIFETIME_MS) {
|
|
133
|
-
throw new Error(
|
|
134
|
-
`[LIOP-PQC] Session secret expired: Age (${Math.round(age / 1e3)}s) exceeds 3600s TTL limit.`
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
if (data.sessionTimestamp > Date.now() + 6e4) {
|
|
138
|
-
throw new Error(
|
|
139
|
-
"[LIOP-PQC] Session secret invalid: Timestamp is in the future."
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
const {
|
|
144
|
-
ciphertext,
|
|
145
|
-
secretKeyObj,
|
|
146
|
-
wasmBinary,
|
|
147
|
-
inputs,
|
|
148
|
-
aesNonce,
|
|
149
|
-
records,
|
|
150
|
-
isEncrypted = true,
|
|
151
|
-
dpConfig
|
|
152
|
-
} = data;
|
|
153
|
-
let decryptedPayload;
|
|
154
|
-
const decryptedInputs = {};
|
|
155
|
-
let sessionSecret = Buffer.alloc(32);
|
|
156
|
-
if (isEncrypted) {
|
|
157
|
-
const sk = new Uint8Array(secretKeyObj);
|
|
158
|
-
const ct = new Uint8Array(ciphertext);
|
|
159
|
-
const kem = await createMlKem768();
|
|
160
|
-
const sharedSecret = kem.decap(ct, sk);
|
|
161
|
-
const aesKey = Buffer.from(sharedSecret);
|
|
162
|
-
sessionSecret = aesKey;
|
|
163
|
-
const wasmBuffer = Buffer.from(wasmBinary);
|
|
164
|
-
const authTag = wasmBuffer.subarray(-16);
|
|
165
|
-
const encryptedData = wasmBuffer.subarray(0, -16);
|
|
166
|
-
const decipher = crypto2.createDecipheriv(
|
|
167
|
-
"aes-256-gcm",
|
|
168
|
-
aesKey,
|
|
169
|
-
Buffer.from(aesNonce || new Uint8Array(12))
|
|
170
|
-
);
|
|
171
|
-
decipher.setAuthTag(authTag);
|
|
172
|
-
let decrypted = decipher.update(encryptedData);
|
|
173
|
-
decrypted = Buffer.concat([decrypted, decipher.final()]);
|
|
174
|
-
decryptedPayload = decrypted;
|
|
175
|
-
for (const [key, encValue] of Object.entries(inputs || {})) {
|
|
176
|
-
const valBuffer = Buffer.from(encValue);
|
|
177
|
-
const inputNonce = valBuffer.subarray(0, 12);
|
|
178
|
-
const valTag = valBuffer.subarray(-16);
|
|
179
|
-
const valData = valBuffer.subarray(12, -16);
|
|
180
|
-
const valDecipher = crypto2.createDecipheriv(
|
|
181
|
-
"aes-256-gcm",
|
|
182
|
-
aesKey,
|
|
183
|
-
inputNonce
|
|
184
|
-
);
|
|
185
|
-
valDecipher.setAuthTag(valTag);
|
|
186
|
-
let valDecrypted = valDecipher.update(valData);
|
|
187
|
-
valDecrypted = Buffer.concat([valDecrypted, valDecipher.final()]);
|
|
188
|
-
decryptedInputs[key] = JSON.parse(valDecrypted.toString("utf-8"));
|
|
189
|
-
}
|
|
190
|
-
} else {
|
|
191
|
-
if (wasmBinary[0] === 0 && wasmBinary[1] === 97 && wasmBinary[2] === 115 && wasmBinary[3] === 109) {
|
|
192
|
-
decryptedPayload = Buffer.from(wasmBinary);
|
|
193
|
-
} else {
|
|
194
|
-
decryptedPayload = Buffer.from(wasmBinary).toString("utf-8");
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
const isWasm = decryptedPayload[0] === 0 && decryptedPayload[1] === 97 && decryptedPayload[2] === 115 && decryptedPayload[3] === 109;
|
|
198
|
-
if (decryptedPayload instanceof Buffer && isWasm) {
|
|
199
|
-
const wasmBytes = new Uint8Array(decryptedPayload);
|
|
200
|
-
const compiledModule = await WebAssembly.compile(wasmBytes);
|
|
201
|
-
ASTGuardian.analyze(compiledModule);
|
|
202
|
-
} else if (decryptedPayload instanceof Buffer && !isWasm) {
|
|
203
|
-
decryptedPayload = decryptedPayload.toString("utf-8");
|
|
204
|
-
}
|
|
205
|
-
if (typeof decryptedPayload === "string") {
|
|
206
|
-
decryptedPayload = normalizeLogicSource(decryptedPayload);
|
|
207
|
-
}
|
|
208
|
-
const sandbox = new WasiSandbox();
|
|
209
|
-
await sandbox.init();
|
|
210
|
-
try {
|
|
211
|
-
const result = await sandbox.execute(
|
|
212
|
-
decryptedPayload,
|
|
213
|
-
records,
|
|
214
|
-
decryptedInputs
|
|
215
|
-
);
|
|
216
|
-
let finalOutput = result.output;
|
|
217
|
-
let logicBytes;
|
|
218
|
-
if (typeof decryptedPayload === "string") {
|
|
219
|
-
logicBytes = Buffer.from(decryptedPayload, "utf-8");
|
|
220
|
-
} else {
|
|
221
|
-
logicBytes = new Uint8Array(decryptedPayload);
|
|
222
|
-
}
|
|
223
|
-
const imageId = deriveLogicImageDigest(logicBytes).toString("hex");
|
|
224
|
-
const datasetHash = crypto2.createHash("sha256").update(JSON.stringify(records || [])).digest("hex");
|
|
225
|
-
if (dpConfig) {
|
|
226
|
-
finalOutput = applyDpToOutput(
|
|
227
|
-
finalOutput,
|
|
228
|
-
{
|
|
229
|
-
...dpConfig,
|
|
230
|
-
seed: `${datasetHash}:${imageId}`
|
|
231
|
-
},
|
|
232
|
-
records?.length || 0
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
finalOutput = sanitizeOutput(finalOutput);
|
|
236
|
-
const journal = Buffer.from(
|
|
237
|
-
JSON.stringify({
|
|
238
|
-
image_id: imageId,
|
|
239
|
-
dataset_hash: datasetHash,
|
|
240
|
-
output_hash: crypto2.createHash("sha256").update(
|
|
241
|
-
typeof finalOutput === "string" ? finalOutput : finalOutput === void 0 ? "undefined" : JSON.stringify(finalOutput)
|
|
242
|
-
).digest("hex"),
|
|
243
|
-
fuel: result.fuelConsumed,
|
|
244
|
-
ts: Date.now()
|
|
245
|
-
})
|
|
246
|
-
);
|
|
247
|
-
const seal = crypto2.createHmac("sha256", sessionSecret).update(journal).digest();
|
|
248
|
-
const journalLen = Buffer.alloc(2);
|
|
249
|
-
journalLen.writeUInt16BE(journal.length);
|
|
250
|
-
const receiptBuf = Buffer.concat([
|
|
251
|
-
Buffer.from([1]),
|
|
252
|
-
// Receipt format v1
|
|
253
|
-
journalLen,
|
|
254
|
-
journal,
|
|
255
|
-
seal
|
|
256
|
-
// 32 bytes HMAC
|
|
257
|
-
]);
|
|
258
|
-
const zkReceipt = receiptBuf.toString("base64");
|
|
259
|
-
return {
|
|
260
|
-
image_id: imageId,
|
|
261
|
-
zk_receipt: zkReceipt,
|
|
262
|
-
output: finalOutput,
|
|
263
|
-
fuel_consumed: result.fuelConsumed
|
|
264
|
-
};
|
|
265
|
-
} finally {
|
|
266
|
-
await sandbox.teardown();
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
export { processLogicExecution as default };
|
|
271
|
-
//# sourceMappingURL=logic-execution.js.map
|
|
1
|
+
import {a as a$1,d}from'../chunk-CTTTLCGL.js';import {a as a$3}from'../chunk-MQ5SU26J.js';import {a as a$2,b}from'../chunk-TKLRW52V.js';import {b as b$1}from'../chunk-2ZYX736J.js';import {f,h}from'../chunk-6VK2XALI.js';import {a}from'../chunk-AYDF3IFZ.js';import {Buffer}from'buffer';import m from'crypto';import {createMlKem768}from'mlkem';var Y={epsilon:1,sensitivity:1,smallDatasetThreshold:50},J=1,ee=10;function te(e,i){let o;do if(i)o=m.createHash("sha256").update(`${i.seed}:${i.counter++}`).digest().readUInt32BE(0)/4294967296-.5;else {let t=m.randomBytes(4),a=t[0]<<24|t[1]<<16|t[2]<<8|t[3];o=Number.parseInt(a.toString(10),10)/4294967296;}while(o===0||o===-0.5);return -e*Math.sign(o)*Math.log(1-2*Math.abs(o))}a(te,"laplaceSample");function re(e,i={},o){let t={...Y,...i},a=t.sensitivity/t.epsilon,c=e+te(a,o);return Math.round(c*1e4)/1e4}a(re,"addLaplaceNoise");function $(e,i,o){if(!e)return i;let t=e.toLowerCase(),a=/count|length|size|num|gainer|loser|positive|negative|nan_|null_|empty_|finite_|non_finite_|instruments|tickers|users|records/i.test(t),c=t==="total"||t==="n"||t==="total_records"||t.startsWith("total_")||t.startsWith("num_")||/total.*(count|items|entries|rows|records|tickers)/i.test(t);return a||c?1:/avg|mean|average|var|variance|std|stddev|ratio|bps|drift|pct|percent|imbalance/i.test(t)&&o>0?i/o:i}a($,"deriveFieldSensitivity");function Z(e,i={},o){let t={...Y,...i};if(o>=t.smallDatasetThreshold)return e;o<ee&&t.epsilon<J&&(t.epsilon=J);let a;return t.seed&&(a={seed:t.seed,counter:0}),R(e,t,o,void 0,a)}a(Z,"applyDpToOutput");function R(e,i,o,t,a){if(typeof e=="number"&&Number.isFinite(e)){let c=$(t,i.sensitivity,o),u=re(e,{...i,sensitivity:c},a),w=t!=null&&$(t,i.sensitivity,o)===1;return (Number.isInteger(e)||w)&&(u=Math.round(u)),e>=0&&(u=Math.max(0,u)),u}if(Array.isArray(e))return e.map(c=>R(c,i,o,t,a));if(e!==null&&typeof e=="object"){let c={};for(let[u,w]of Object.entries(e))c[u]=R(w,i,o,u,a);return c}return e}a(R,"walkAndNoise");async function oe(e){if(typeof Object.prototype=="object"&&!Object.isFrozen(Object.prototype)&&(Object.freeze(Object.prototype),Object.freeze(Array.prototype),Object.freeze(String.prototype),Object.freeze(Number.prototype),Object.freeze(Boolean.prototype),Object.freeze(RegExp.prototype),Object.freeze(Map.prototype),Object.freeze(Set.prototype),Object.freeze(Promise.prototype),Object.freeze(Error.prototype)),e.isWarmup)return {image_id:"",output:"warm",fuel_consumed:0};if(e.sessionTimestamp!==void 0){let n=Date.now()-e.sessionTimestamp;if(n>36e5)throw new Error(`[LIOP-PQC] Session secret expired: Age (${Math.round(n/1e3)}s) exceeds 3600s TTL limit.`);if(e.sessionTimestamp>Date.now()+6e4)throw new Error("[LIOP-PQC] Session secret invalid: Timestamp is in the future.")}let{ciphertext:i,secretKeyObj:o,wasmBinary:t,inputs:a,aesNonce:c,records:u,isEncrypted:w=true,dpConfig:z}=e,s,D={},C=Buffer.alloc(32);if(w){let p=new Uint8Array(o),n=new Uint8Array(i),g=(await createMlKem768()).decap(n,p),d=Buffer.from(g);C=d;let _=Buffer.from(t),k=_.subarray(-16),T=_.subarray(0,-16),A=m.createDecipheriv("aes-256-gcm",d,Buffer.from(c||new Uint8Array(12)));A.setAuthTag(k);let S=A.update(T);S=Buffer.concat([S,A.final()]),s=S;for(let[E,B]of Object.entries(a||{})){let y=Buffer.from(B),f=y.subarray(0,12),h=y.subarray(-16),x=y.subarray(12,-16),O=m.createDecipheriv("aes-256-gcm",d,f);O.setAuthTag(h);let v=O.update(x);v=Buffer.concat([v,O.final()]),D[E]=JSON.parse(v.toString("utf-8"));}}else t[0]===0&&t[1]===97&&t[2]===115&&t[3]===109?s=Buffer.from(t):s=Buffer.from(t).toString("utf-8");let K=s[0]===0&&s[1]===97&&s[2]===115&&s[3]===109;if(s instanceof Buffer&&K){let p=new Uint8Array(s),n=await WebAssembly.compile(p);a$1.analyze(n);}else s instanceof Buffer&&!K&&(s=s.toString("utf-8"));typeof s=="string"&&(s=a$2(s));let N=new d;await N.init();try{let p=await N.execute(s,u,D),n=p.output,I;typeof s=="string"?I=Buffer.from(s,"utf-8"):I=new Uint8Array(s);let g=b(I).toString("hex"),d=m.createHash("sha256").update(JSON.stringify(u||[])).digest("hex");if(z&&(n=Z(n,{...z,seed:`${d}:${g}`},u?.length||0)),n=a$3(n),e.proofMode===1||e.proofMode===2){let E=e.guestImageId?Buffer.from(e.guestImageId,"hex"):m.createHash("sha256").update("liop-default-guest-v2").digest(),B=typeof n=="string"?n:n===void 0?"undefined":JSON.stringify(n),y=f({guestImageId:E,logicDigest:Buffer.from(g,"hex"),datasetDigest:Buffer.from(d,"hex"),outputDigest:m.createHash("sha256").update(B).digest(),fuelConsumed:BigInt(p.fuelConsumed),executionTimestamp:BigInt(Date.now())}),f$1,h$1=null;try{h$1=await import('@nekzus/liop-zk-native');}catch{h$1=null;}if(h$1&&typeof h$1.prove_analytical_query=="function")try{let b=typeof D?.operation=="string"?D.operation:"sum",M=JSON.stringify({records:Array.isArray(u)?u.map(P=>Number(P.amount??P.value??1)):[1],expected_sum:typeof n=="number"?n:void 0});f$1=await h$1.prove_analytical_query(b,M);}catch(b){if(e.proofMode===2)throw new Error(`ZK PROOF GENERATION FAILED: Native Groth16 prover execution error: ${b instanceof Error?b.message:String(b)}`);f$1=Buffer.alloc(128,66);}else {if(e.proofMode===2)throw new Error("ZK PROOF GENERATION FAILED: Native Groth16 prover module unavailable for required policy.");f$1=Buffer.alloc(128,66);}let x,O=2;if(e.pqcSigningKey&&e.pqcSigningKey.length>0){O=3;let b=m.createHash("sha256").update(Buffer.concat([y,f$1])).digest(),M=b$1.sign(b,e.pqcSigningKey),P=b$1.getPublicKey(e.pqcSigningKey);x=h.encodeHybridV2(y,f$1,Buffer.from(M),Buffer.from(P));}else x=h.encodeV2(2,y,f$1);let v=x.toString("base64");return {image_id:g,zk_receipt:v,output:n,fuel_consumed:p.fuelConsumed,proof_type:O,guest_image_id:E.toString("hex")}}let _=Buffer.from(JSON.stringify({image_id:g,dataset_hash:d,output_hash:m.createHash("sha256").update(typeof n=="string"?n:n===void 0?"undefined":JSON.stringify(n)).digest("hex"),fuel:p.fuelConsumed,ts:Date.now()})),k=m.createHmac("sha256",C).update(_).digest(),T=Buffer.alloc(2);T.writeUInt16BE(_.length);let S=Buffer.concat([Buffer.from([1]),T,_,k]).toString("base64");return {image_id:g,zk_receipt:S,output:n,fuel_consumed:p.fuelConsumed,proof_type:0}}finally{await N.teardown();}}a(oe,"processLogicExecution");export{oe as default};//# sourceMappingURL=logic-execution.js.map
|
|
272
2
|
//# sourceMappingURL=logic-execution.js.map
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Z as ZkPolicy } from '../zk-DzYNWBgo.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* ZK Verification Payload Structure.
|
|
3
5
|
* Modeled after RISC Zero & SP1 Receipt formats.
|
|
@@ -8,12 +10,18 @@ interface ZkVerificationPayload {
|
|
|
8
10
|
logicPayload?: Uint8Array;
|
|
9
11
|
/** Expected ImageID (SHA-256) of the execution state */
|
|
10
12
|
remoteImageIdHex?: string;
|
|
13
|
+
/** Expected Guest ImageID (SHA-256) of the zkVM interpreter */
|
|
14
|
+
guestImageIdHex?: string;
|
|
11
15
|
/** Cbor-encoded or raw buffer containing the execution Receipt (Journal + Seal) */
|
|
12
16
|
zkReceipt?: Uint8Array;
|
|
13
17
|
/** Kyber-derived session secret to verify HMAC signature */
|
|
14
18
|
sessionSecret?: Uint8Array;
|
|
19
|
+
/** Serialized VerificationKey buffer for Groth16 mathematical verification */
|
|
20
|
+
vkeyRaw?: Uint8Array;
|
|
15
21
|
/** The expected output value of the computation for anti-replay/tampering verification */
|
|
16
22
|
expectedOutput?: unknown;
|
|
23
|
+
/** Enforcement policy for clearance tiers */
|
|
24
|
+
zkPolicy?: ZkPolicy;
|
|
17
25
|
}
|
|
18
26
|
/**
|
|
19
27
|
* Main worker entry point for Piscina.
|
|
@@ -21,6 +29,7 @@ interface ZkVerificationPayload {
|
|
|
21
29
|
declare function workerHandler(task: ZkVerificationPayload): Promise<{
|
|
22
30
|
verified: boolean;
|
|
23
31
|
message: string;
|
|
32
|
+
proofType?: string;
|
|
24
33
|
}>;
|
|
25
34
|
|
|
26
35
|
export { type ZkVerificationPayload, workerHandler as default };
|
|
@@ -1,174 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import crypto from 'crypto';
|
|
3
|
-
import 'worker_threads';
|
|
4
|
-
|
|
5
|
-
function deriveImageId(logicPayload) {
|
|
6
|
-
return deriveLogicImageDigest(logicPayload);
|
|
7
|
-
}
|
|
8
|
-
function tryExtractProxyOutput(logicPayload) {
|
|
9
|
-
try {
|
|
10
|
-
const logicStr = Buffer.from(logicPayload).toString("utf-8").trim();
|
|
11
|
-
if (!logicStr.includes("__liop_proxy_tool")) {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
const firstBraceIdx = logicStr.indexOf("{");
|
|
15
|
-
if (firstBraceIdx === -1) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
let braceCount = 0;
|
|
19
|
-
let inDoubleQuote = false;
|
|
20
|
-
let inSingleQuote = false;
|
|
21
|
-
let inBacktick = false;
|
|
22
|
-
let escaped = false;
|
|
23
|
-
let lastBraceIdx = -1;
|
|
24
|
-
for (let i = firstBraceIdx; i < logicStr.length; i++) {
|
|
25
|
-
const char = logicStr[i];
|
|
26
|
-
if (escaped) {
|
|
27
|
-
escaped = false;
|
|
28
|
-
continue;
|
|
29
|
-
}
|
|
30
|
-
if (char === "\\") {
|
|
31
|
-
escaped = true;
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
if (char === '"' && !inSingleQuote && !inBacktick) {
|
|
35
|
-
inDoubleQuote = !inDoubleQuote;
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
if (char === "'" && !inDoubleQuote && !inBacktick) {
|
|
39
|
-
inSingleQuote = !inSingleQuote;
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
if (char === "`" && !inDoubleQuote && !inSingleQuote) {
|
|
43
|
-
inBacktick = !inBacktick;
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
if (!inDoubleQuote && !inSingleQuote && !inBacktick) {
|
|
47
|
-
if (char === "{") {
|
|
48
|
-
braceCount++;
|
|
49
|
-
} else if (char === "}") {
|
|
50
|
-
braceCount--;
|
|
51
|
-
if (braceCount === 0) {
|
|
52
|
-
lastBraceIdx = i;
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (lastBraceIdx !== -1) {
|
|
59
|
-
const jsonStr = logicStr.slice(firstBraceIdx, lastBraceIdx + 1);
|
|
60
|
-
const parsed = JSON.parse(jsonStr);
|
|
61
|
-
if (parsed?.__liop_proxy_tool) {
|
|
62
|
-
return parsed;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
} catch (_e) {
|
|
66
|
-
}
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
async function verifyZkReceipt(payload) {
|
|
70
|
-
const {
|
|
71
|
-
logicPayload,
|
|
72
|
-
remoteImageIdHex,
|
|
73
|
-
zkReceipt,
|
|
74
|
-
sessionSecret,
|
|
75
|
-
expectedOutput
|
|
76
|
-
} = payload;
|
|
77
|
-
if (!logicPayload || !remoteImageIdHex || !zkReceipt) {
|
|
78
|
-
return {
|
|
79
|
-
verified: false,
|
|
80
|
-
message: "Missing required verification fields."
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
const localImageId = deriveImageId(logicPayload);
|
|
84
|
-
const localImageIdHex = localImageId.toString("hex");
|
|
85
|
-
if (localImageIdHex !== remoteImageIdHex) {
|
|
86
|
-
return {
|
|
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) {
|
|
100
|
-
return {
|
|
101
|
-
verified: false,
|
|
102
|
-
message: `Unknown receipt version: ${version}`
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
const journalLen = receiptBuf.readUInt16BE(1);
|
|
106
|
-
const journal = receiptBuf.subarray(3, 3 + journalLen);
|
|
107
|
-
const seal = receiptBuf.subarray(3 + journalLen);
|
|
108
|
-
if (seal.length !== 32) {
|
|
109
|
-
return {
|
|
110
|
-
verified: false,
|
|
111
|
-
message: "Invalid seal length (expected 32 bytes HMAC-SHA256)."
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
let journalData;
|
|
115
|
-
try {
|
|
116
|
-
journalData = JSON.parse(journal.toString());
|
|
117
|
-
if (journalData.image_id !== localImageIdHex) {
|
|
118
|
-
return {
|
|
119
|
-
verified: false,
|
|
120
|
-
message: `Journal ImageID mismatch: ${journalData.image_id.slice(0, 8)} != ${localImageIdHex.slice(0, 8)}`
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
} catch (_e) {
|
|
124
|
-
return { verified: false, message: "Failed to parse journal data." };
|
|
125
|
-
}
|
|
126
|
-
if (sessionSecret && sessionSecret.length > 0) {
|
|
127
|
-
const expectedSeal = crypto.createHmac("sha256", sessionSecret).update(journal).digest();
|
|
128
|
-
if (!crypto.timingSafeEqual(seal, expectedSeal)) {
|
|
129
|
-
return {
|
|
130
|
-
verified: false,
|
|
131
|
-
message: "Invalid seal: HMAC verification failed."
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
if (expectedOutput !== void 0) {
|
|
136
|
-
const proxyOutput = tryExtractProxyOutput(logicPayload);
|
|
137
|
-
const actualExpected = proxyOutput !== null ? proxyOutput : expectedOutput;
|
|
138
|
-
const expectedOutputStr = typeof actualExpected === "string" ? actualExpected : actualExpected === void 0 ? "undefined" : JSON.stringify(actualExpected);
|
|
139
|
-
const expectedOutputHash = crypto.createHash("sha256").update(expectedOutputStr).digest("hex");
|
|
140
|
-
if (journalData.output_hash !== expectedOutputHash) {
|
|
141
|
-
return {
|
|
142
|
-
verified: false,
|
|
143
|
-
message: `Output Hash Mismatch (Replay/Tamper attempt): Journal output_hash (${journalData.output_hash.slice(0, 8)}) != Calculated output_hash (${expectedOutputHash.slice(0, 8)})`
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
return {
|
|
148
|
-
verified: true,
|
|
149
|
-
message: "HMAC Commitment Verified: Integrity intact."
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
async function workerHandler(task) {
|
|
153
|
-
try {
|
|
154
|
-
if (task.action === "warmup") {
|
|
155
|
-
return {
|
|
156
|
-
verified: true,
|
|
157
|
-
message: "warm"
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
if (task.action === "verify_receipt") {
|
|
161
|
-
return await verifyZkReceipt(task);
|
|
162
|
-
}
|
|
163
|
-
throw new Error("Unknown action in ZkVerifier Worker.");
|
|
164
|
-
} catch (error) {
|
|
165
|
-
return {
|
|
166
|
-
verified: false,
|
|
167
|
-
message: `Verification Error: ${error.message}`
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export { workerHandler as default };
|
|
173
|
-
//# sourceMappingURL=zk-verifier.js.map
|
|
1
|
+
import {d,f,b as b$3}from'../chunk-FDJMH4CB.js';import {b}from'../chunk-TKLRW52V.js';import {b as b$2}from'../chunk-2ZYX736J.js';import {h,b as b$1,c,g}from'../chunk-6VK2XALI.js';import {a}from'../chunk-AYDF3IFZ.js';import v from'crypto';import'worker_threads';function D(s){return b(s)}a(D,"deriveImageId");function O(s){try{let i=Buffer.from(s).toString("utf-8").trim();if(!i.includes("__liop_proxy_tool"))return null;let d=i.indexOf("{");if(d===-1)return null;let p=0,c=!1,n=!1,o=!1,f=!1,y=-1;for(let e=d;e<i.length;e++){let t=i[e];if(f){f=!1;continue}if(t==="\\"){f=!0;continue}if(t==='"'&&!n&&!o){c=!c;continue}if(t==="'"&&!c&&!o){n=!n;continue}if(t==="`"&&!c&&!n){o=!o;continue}if(!c&&!n&&!o){if(t==="{")p++;else if(t==="}"&&(p--,p===0)){y=e;break}}}if(y!==-1){let e=i.slice(d,y+1),t=JSON.parse(e);if(t?.__liop_proxy_tool)return t}}catch{}return null}a(O,"tryExtractProxyOutput");async function T(s){let{logicPayload:i,remoteImageIdHex:d$1,guestImageIdHex:p,zkReceipt:c$1,sessionSecret:n,vkeyRaw:o,expectedOutput:f$1,zkPolicy:y}=s;if(!i||!d$1||!c$1)return {verified:false,message:"Missing required verification fields."};let e;try{e=h.decode(Buffer.from(c$1));}catch(t){return {verified:false,message:`Receipt Decode Failed: ${t.message}`}}if(e.version===b$1){if(y==="required")return {verified:false,message:"Policy Violation: Clearance Tier requires ZK proof (Groth16), but received legacy HMAC."};let g=D(i).toString("hex");if(g!==d$1)return {verified:false,message:`Integrity Violation: Local (${g.slice(0,8)}) != Remote (${d$1.slice(0,8)})`};let u;try{if(u=JSON.parse(e.journal.toString()),u.image_id!==g)return {verified:!1,message:`Journal ImageID mismatch: ${u.image_id.slice(0,8)} != ${g.slice(0,8)}`}}catch{return {verified:false,message:"Failed to parse journal data."}}if(n&&n.length>0){let r=v.createHmac("sha256",n).update(e.journal).digest();if(!v.timingSafeEqual(e.proof,r))return {verified:false,message:"Invalid seal: HMAC verification failed."}}if(f$1!==void 0){let r=O(i),a=r!==null?r:f$1,m=typeof a=="string"?a:a===void 0?"undefined":JSON.stringify(a),l=v.createHash("sha256").update(m).digest("hex");if(u.output_hash!==l)return {verified:false,message:`Output Hash Mismatch (Replay/Tamper attempt): Journal output_hash (${u.output_hash.slice(0,8)}) != Calculated output_hash (${l.slice(0,8)})`}}return {verified:true,message:"HMAC Commitment Verified: Integrity intact.",proofType:"hmac"}}if(e.version===c){if(e.proofType!==2&&e.proofType!==3)return {verified:false,message:`Unsupported ZK proof type in v2 receipt: ${e.proofType}`};if(e.proofType===3){let{pqcSignature:r,pqcPublicKey:a}=e;if(!r||!a)return {verified:false,message:"Hybrid Receipt Error: Missing ML-DSA-65 signature or public key."};let m=v.createHash("sha256").update(Buffer.concat([e.journal,e.proof])).digest();try{if(!b$2.verify(new Uint8Array(r),m,new Uint8Array(a)))return {verified:!1,message:"PQC Signature Verification Failed: ML-DSA-65 co-sign is forged or corrupted."}}catch(l){return {verified:false,message:`PQC Verification Error: ${l.message}`}}}let t;try{t=g(e.journal);}catch(r){return {verified:false,message:`Failed to decode ZkJournalV2: ${r.message}`}}if(p){let r=t.guestImageId.toString("hex");if(r!==p)return {verified:false,message:`Guest ImageID Mismatch: Injected guest environment tampered (${r.slice(0,8)} != ${p.slice(0,8)}).`}}let g$1=D(i);if(!t.logicDigest.equals(g$1))return {verified:false,message:`Logic Digest Mismatch: Remote origin executed unexpected logic (${t.logicDigest.toString("hex").slice(0,8)} != ${g$1.toString("hex").slice(0,8)})`};if(o&&o.length>0)try{let r=d(Buffer.from(o)),a=f(e.proof);if(!b$3(r,a))return {verified:!1,message:"Groth16 mathematical pairing verification failed: invalid proof."}}catch(r){return {verified:false,message:`Groth16 verification failed to execute: ${r.message}`}}if(f$1!==void 0){let r=O(i),a=r!==null?r:f$1,m=typeof a=="string"?a:a===void 0?"undefined":JSON.stringify(a),l=v.createHash("sha256").update(m).digest();if(!t.outputDigest.equals(l))return {verified:false,message:`Output Digest Mismatch (Replay/Tamper attempt): Journal (${t.outputDigest.toString("hex").slice(0,8)}) != Calculated (${l.toString("hex").slice(0,8)})`}}let u=e.proofType===3;return {verified:true,message:u?"Groth16 + ML-DSA-65 Post-Quantum Hybrid Receipt Certified.":o&&o.length>0?"Groth16 Zero-Knowledge Proof Mathematically Certified.":"Groth16 Receipt Structure and Journal Integrity Certified.",proofType:u?"groth16_pqc_hybrid":"groth16"}}return {verified:false,message:`Unsupported receipt version: ${e.version}`}}a(T,"verifyZkReceipt");async function C(s){try{if(s.action==="warmup")return {verified:!0,message:"warm"};if(s.action==="verify_receipt")return await T(s);throw new Error("Unknown action in ZkVerifier Worker.")}catch(i){return {verified:false,message:`Verification Error: ${i.message}`}}}a(C,"workerHandler");export{C as default};//# sourceMappingURL=zk-verifier.js.map
|
|
174
2
|
//# sourceMappingURL=zk-verifier.js.map
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
declare enum ProofType {
|
|
2
|
+
HMAC_LEGACY = 0,
|
|
3
|
+
GROTH16 = 2,
|
|
4
|
+
GROTH16_PQC_HYBRID = 3
|
|
5
|
+
}
|
|
6
|
+
declare const RECEIPT_VERSION_V1 = 1;
|
|
7
|
+
declare const RECEIPT_VERSION_V2 = 2;
|
|
8
|
+
declare const ZK_JOURNAL_V2_SIZE = 144;
|
|
9
|
+
interface ZkJournalV2 {
|
|
10
|
+
/** Image ID (SHA-256) of the guest interpreter */
|
|
11
|
+
guestImageId: Buffer;
|
|
12
|
+
/** SHA-256 digest of injected logic */
|
|
13
|
+
logicDigest: Buffer;
|
|
14
|
+
/** SHA-256 digest of dataset records */
|
|
15
|
+
datasetDigest: Buffer;
|
|
16
|
+
/** SHA-256 digest of sanitized output */
|
|
17
|
+
outputDigest: Buffer;
|
|
18
|
+
/** Micro-instruction fuel consumed */
|
|
19
|
+
fuelConsumed: bigint;
|
|
20
|
+
/** Timestamp in milliseconds since unix epoch */
|
|
21
|
+
executionTimestamp: bigint;
|
|
22
|
+
}
|
|
23
|
+
type ZkPolicy = "none" | "optimistic" | "required";
|
|
24
|
+
interface ZkReceipt {
|
|
25
|
+
/** Cryptographic proof generated by a zero-knowledge VM (e.g., RISC Zero, SP1) or Groth16 */
|
|
26
|
+
proof: Buffer;
|
|
27
|
+
/** The public inputs/outputs of the execution (the "Journal" in RISC Zero terminology) */
|
|
28
|
+
journal: Buffer;
|
|
29
|
+
/** The expected image ID / verification key of the WASM binary that was executed */
|
|
30
|
+
imageId: Buffer;
|
|
31
|
+
/** Type of cryptographic proof (HMAC legacy or Groth16) */
|
|
32
|
+
proofType?: ProofType;
|
|
33
|
+
/** Binary receipt version (0x01 or 0x02) */
|
|
34
|
+
version?: number;
|
|
35
|
+
}
|
|
36
|
+
declare class ZkVerificationError extends Error {
|
|
37
|
+
constructor(message: string);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Serializes a structured ZkJournalV2 into a strictly validated 144-byte binary layout.
|
|
41
|
+
*/
|
|
42
|
+
declare function encodeJournalV2(fields: ZkJournalV2): Buffer;
|
|
43
|
+
/**
|
|
44
|
+
* Deserializes and validates a 144-byte binary buffer into a typed ZkJournalV2.
|
|
45
|
+
*/
|
|
46
|
+
declare function decodeJournalV2(buf: Buffer): ZkJournalV2;
|
|
47
|
+
interface DecodedReceipt {
|
|
48
|
+
version: number;
|
|
49
|
+
proofType: ProofType;
|
|
50
|
+
journal: Buffer;
|
|
51
|
+
proof: Buffer;
|
|
52
|
+
raw: Buffer;
|
|
53
|
+
pqcSignature?: Buffer;
|
|
54
|
+
pqcPublicKey?: Buffer;
|
|
55
|
+
}
|
|
56
|
+
declare const receiptCodec: {
|
|
57
|
+
/**
|
|
58
|
+
* Encodes a version 2 Binary Receipt with trailing SHA-256 checksum.
|
|
59
|
+
* Layout: [0x02][proofType: 1B][journalLen: 4B UInt32BE][journal][proof][checksum: 32B]
|
|
60
|
+
*/
|
|
61
|
+
encodeV2(proofType: ProofType, journal: Buffer, proof: Buffer): Buffer;
|
|
62
|
+
/**
|
|
63
|
+
* Encodes a version 2.1 Hybrid Binary Receipt (Groth16 + ML-DSA-65 co-sign).
|
|
64
|
+
* Layout:
|
|
65
|
+
* [0x02][0x03 ProofType.GROTH16_PQC_HYBRID][journalLen: 4B UInt32BE][journal: 144B]
|
|
66
|
+
* [proofLen: 2B UInt16BE][groth16 proof: ~260B]
|
|
67
|
+
* [sigLen: 2B UInt16BE][signature: 3309B]
|
|
68
|
+
* [publicKey: 1952B]
|
|
69
|
+
* [checksum: 32B SHA-256]
|
|
70
|
+
*/
|
|
71
|
+
encodeHybridV2(journal: Buffer, proof: Buffer, pqcSignature: Buffer, pqcPublicKey: Buffer): Buffer;
|
|
72
|
+
/**
|
|
73
|
+
* Decodes any LIOP Binary Receipt (v1 HMAC or v2 ZK).
|
|
74
|
+
*/
|
|
75
|
+
decode(raw: Buffer): DecodedReceipt;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* ZK-Proofs Verifier for Logic-Injection-on-Origin Protocol (LIOP)
|
|
79
|
+
*
|
|
80
|
+
* Validates that an executed Logic (WASM) actually produced the reported output,
|
|
81
|
+
* verifying the Zero-Knowledge receipt generated by the remote host's Trusted Execution
|
|
82
|
+
* Environment (TEE) or zkVM (Zero-Knowledge Virtual Machine).
|
|
83
|
+
*/
|
|
84
|
+
declare const ZkVerifier: {
|
|
85
|
+
/**
|
|
86
|
+
* Validates a ZK receipt using structural Binary Receipt verification.
|
|
87
|
+
* Parses the HMAC-SHA256 commitment format (v1) and verifies journal integrity.
|
|
88
|
+
*
|
|
89
|
+
* @param receipt - Complete ZkReceipt to verify
|
|
90
|
+
* @param expectedImageId - Hash or ImageID of the WASM file dispatched to the host
|
|
91
|
+
* @throws ZkVerificationError if the proof is invalid or image IDs mismatch
|
|
92
|
+
* @returns true if the proof mathematically verifies the execution
|
|
93
|
+
*/
|
|
94
|
+
verify(receipt: ZkReceipt, expectedImageId: Buffer, sessionSecret?: Buffer): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Derives a predictable ImageID (usually a Hash) from a raw WASM binary.
|
|
97
|
+
*
|
|
98
|
+
* @param wasmBytes - The raw bytes of the WASM logic file
|
|
99
|
+
* @returns The SHA-256 ImageID of the logic
|
|
100
|
+
*/
|
|
101
|
+
deriveImageId(wasmBytes: Buffer): Buffer;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
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 };
|