@longarc/mdash 3.0.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.
- package/README.md +278 -0
- package/dist/checkpoint/engine.d.ts +208 -0
- package/dist/checkpoint/engine.d.ts.map +1 -0
- package/dist/checkpoint/engine.js +369 -0
- package/dist/checkpoint/engine.js.map +1 -0
- package/dist/context/engine.d.ts +197 -0
- package/dist/context/engine.d.ts.map +1 -0
- package/dist/context/engine.js +392 -0
- package/dist/context/engine.js.map +1 -0
- package/dist/core/commitment.d.ts +154 -0
- package/dist/core/commitment.d.ts.map +1 -0
- package/dist/core/commitment.js +305 -0
- package/dist/core/commitment.js.map +1 -0
- package/dist/core/crypto.d.ts +100 -0
- package/dist/core/crypto.d.ts.map +1 -0
- package/dist/core/crypto.js +243 -0
- package/dist/core/crypto.js.map +1 -0
- package/dist/index.d.ts +121 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +234 -0
- package/dist/index.js.map +1 -0
- package/dist/mcca/engine.d.ts +260 -0
- package/dist/mcca/engine.d.ts.map +1 -0
- package/dist/mcca/engine.js +518 -0
- package/dist/mcca/engine.js.map +1 -0
- package/dist/physics/engine.d.ts +165 -0
- package/dist/physics/engine.d.ts.map +1 -0
- package/dist/physics/engine.js +371 -0
- package/dist/physics/engine.js.map +1 -0
- package/dist/tee/engine.d.ts +285 -0
- package/dist/tee/engine.d.ts.map +1 -0
- package/dist/tee/engine.js +505 -0
- package/dist/tee/engine.js.map +1 -0
- package/dist/warrant/engine.d.ts +195 -0
- package/dist/warrant/engine.d.ts.map +1 -0
- package/dist/warrant/engine.js +409 -0
- package/dist/warrant/engine.js.map +1 -0
- package/dist/zk/engine.d.ts +243 -0
- package/dist/zk/engine.d.ts.map +1 -0
- package/dist/zk/engine.js +489 -0
- package/dist/zk/engine.js.map +1 -0
- package/package.json +25 -0
- package/src/__tests__/phase1.test.ts +1120 -0
- package/src/__tests__/phase2-4.test.ts +898 -0
- package/src/checkpoint/engine.ts +532 -0
- package/src/context/engine.ts +598 -0
- package/src/core/commitment.ts +438 -0
- package/src/core/crypto.ts +304 -0
- package/src/index.ts +320 -0
- package/src/mcca/engine.ts +778 -0
- package/src/physics/engine.ts +563 -0
- package/src/tee/engine.ts +810 -0
- package/src/warrant/engine.ts +625 -0
- package/src/zk/engine.ts +730 -0
- package/tsconfig.json +21 -0
package/src/zk/engine.ts
ADDED
|
@@ -0,0 +1,730 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mdash v3.0 - L3 ZK Proofs Layer
|
|
3
|
+
*
|
|
4
|
+
* Mathematically bulletproof attestation for disputes and insurance claims.
|
|
5
|
+
* Uses Plonky2 (STARK-based) for async proof generation.
|
|
6
|
+
*
|
|
7
|
+
* Use Cases:
|
|
8
|
+
* - Insurance claim verification
|
|
9
|
+
* - Legal dispute evidence
|
|
10
|
+
* - Audit compliance
|
|
11
|
+
* - High-value transaction attestation
|
|
12
|
+
*
|
|
13
|
+
* Latency: 100ms - 10s (async, background)
|
|
14
|
+
* Trust: Mathematical only (no hardware dependency)
|
|
15
|
+
*
|
|
16
|
+
* @version 3.0.0
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
Hash,
|
|
21
|
+
Seal,
|
|
22
|
+
Timestamp,
|
|
23
|
+
generateTimestamp,
|
|
24
|
+
sha256,
|
|
25
|
+
sha256Object,
|
|
26
|
+
hmacSeal,
|
|
27
|
+
deriveKey,
|
|
28
|
+
} from '../core/crypto.js';
|
|
29
|
+
|
|
30
|
+
import { CommitmentEngine, Commitment } from '../core/commitment.js';
|
|
31
|
+
import { AttestationDocument } from '../tee/engine.js';
|
|
32
|
+
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// ZK PROOF TYPES
|
|
35
|
+
// ============================================================================
|
|
36
|
+
|
|
37
|
+
export type ProofStatus =
|
|
38
|
+
| 'queued'
|
|
39
|
+
| 'proving'
|
|
40
|
+
| 'verified'
|
|
41
|
+
| 'failed'
|
|
42
|
+
| 'expired';
|
|
43
|
+
|
|
44
|
+
export type ProofType =
|
|
45
|
+
| 'commitment_inclusion' // Prove data is in commitment tree
|
|
46
|
+
| 'warrant_validity' // Prove warrant was valid at time
|
|
47
|
+
| 'checkpoint_chain' // Prove checkpoint sequence
|
|
48
|
+
| 'action_compliance' // Prove action met constraints
|
|
49
|
+
| 'audit_trail' // Prove complete audit trail
|
|
50
|
+
| 'custom'; // Custom circuit
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Plonky2 proof structure
|
|
54
|
+
* Based on Polygon's Plonky2 implementation
|
|
55
|
+
*/
|
|
56
|
+
export interface Plonky2Proof {
|
|
57
|
+
/** Proof bytes (base64 encoded) */
|
|
58
|
+
proof: string;
|
|
59
|
+
/** Public inputs */
|
|
60
|
+
public_inputs: string[];
|
|
61
|
+
/** Verification key hash */
|
|
62
|
+
verifier_key_hash: Hash;
|
|
63
|
+
/** Circuit type */
|
|
64
|
+
circuit: string;
|
|
65
|
+
/** Number of gates */
|
|
66
|
+
num_gates: number;
|
|
67
|
+
/** Proving time (ms) */
|
|
68
|
+
proving_time_ms: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Zero Knowledge Proof Document
|
|
73
|
+
*/
|
|
74
|
+
export interface ZKProofDocument {
|
|
75
|
+
/** Unique proof ID */
|
|
76
|
+
id: string;
|
|
77
|
+
/** Type of proof */
|
|
78
|
+
type: ProofType;
|
|
79
|
+
/** Creation timestamp */
|
|
80
|
+
timestamp: Timestamp;
|
|
81
|
+
/** Status */
|
|
82
|
+
status: ProofStatus;
|
|
83
|
+
/** Statement being proven */
|
|
84
|
+
statement: {
|
|
85
|
+
/** Human readable description */
|
|
86
|
+
description: string;
|
|
87
|
+
/** Structured claim */
|
|
88
|
+
claim: Record<string, unknown>;
|
|
89
|
+
/** Hash of the claim */
|
|
90
|
+
claim_hash: Hash;
|
|
91
|
+
};
|
|
92
|
+
/** The ZK proof itself */
|
|
93
|
+
proof: Plonky2Proof | null;
|
|
94
|
+
/** References to L1/L2 attestations */
|
|
95
|
+
references: {
|
|
96
|
+
commitments: string[];
|
|
97
|
+
attestations: string[];
|
|
98
|
+
};
|
|
99
|
+
/** Verification result */
|
|
100
|
+
verification: {
|
|
101
|
+
verified: boolean;
|
|
102
|
+
verified_at: Timestamp | null;
|
|
103
|
+
verifier: string | null;
|
|
104
|
+
};
|
|
105
|
+
/** Expiry */
|
|
106
|
+
expires_at: Timestamp;
|
|
107
|
+
/** Seal */
|
|
108
|
+
seal: Seal;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Proof request
|
|
113
|
+
*/
|
|
114
|
+
export interface ProofRequest {
|
|
115
|
+
type: ProofType;
|
|
116
|
+
statement: {
|
|
117
|
+
description: string;
|
|
118
|
+
claim: Record<string, unknown>;
|
|
119
|
+
};
|
|
120
|
+
commitmentIds?: string[];
|
|
121
|
+
attestationIds?: string[];
|
|
122
|
+
priority?: 'low' | 'normal' | 'high';
|
|
123
|
+
deadline?: Timestamp;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ============================================================================
|
|
127
|
+
// CIRCUIT DEFINITIONS
|
|
128
|
+
// ============================================================================
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Circuit configuration
|
|
132
|
+
* Defines the structure for each proof type
|
|
133
|
+
*/
|
|
134
|
+
export interface CircuitConfig {
|
|
135
|
+
name: string;
|
|
136
|
+
numPublicInputs: number;
|
|
137
|
+
numPrivateInputs: number;
|
|
138
|
+
estimatedGates: number;
|
|
139
|
+
estimatedProvingTimeMs: number;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export const CIRCUIT_CONFIGS: Record<ProofType, CircuitConfig> = {
|
|
143
|
+
commitment_inclusion: {
|
|
144
|
+
name: 'MerkleInclusionCircuit',
|
|
145
|
+
numPublicInputs: 2, // root, leaf
|
|
146
|
+
numPrivateInputs: 32, // path (max depth 32)
|
|
147
|
+
estimatedGates: 50000,
|
|
148
|
+
estimatedProvingTimeMs: 500,
|
|
149
|
+
},
|
|
150
|
+
warrant_validity: {
|
|
151
|
+
name: 'WarrantValidityCircuit',
|
|
152
|
+
numPublicInputs: 4, // warrant_hash, timestamp, agent_id_hash, action_hash
|
|
153
|
+
numPrivateInputs: 10, // warrant fields
|
|
154
|
+
estimatedGates: 100000,
|
|
155
|
+
estimatedProvingTimeMs: 1000,
|
|
156
|
+
},
|
|
157
|
+
checkpoint_chain: {
|
|
158
|
+
name: 'CheckpointChainCircuit',
|
|
159
|
+
numPublicInputs: 3, // start, end, chain_length
|
|
160
|
+
numPrivateInputs: 100, // checkpoints
|
|
161
|
+
estimatedGates: 500000,
|
|
162
|
+
estimatedProvingTimeMs: 5000,
|
|
163
|
+
},
|
|
164
|
+
action_compliance: {
|
|
165
|
+
name: 'ActionComplianceCircuit',
|
|
166
|
+
numPublicInputs: 5, // action_hash, constraints_hash, result
|
|
167
|
+
numPrivateInputs: 20, // action params, constraint values
|
|
168
|
+
estimatedGates: 150000,
|
|
169
|
+
estimatedProvingTimeMs: 1500,
|
|
170
|
+
},
|
|
171
|
+
audit_trail: {
|
|
172
|
+
name: 'AuditTrailCircuit',
|
|
173
|
+
numPublicInputs: 4, // root, start_time, end_time, num_events
|
|
174
|
+
numPrivateInputs: 1000, // events
|
|
175
|
+
estimatedGates: 2000000,
|
|
176
|
+
estimatedProvingTimeMs: 20000,
|
|
177
|
+
},
|
|
178
|
+
custom: {
|
|
179
|
+
name: 'CustomCircuit',
|
|
180
|
+
numPublicInputs: 10,
|
|
181
|
+
numPrivateInputs: 100,
|
|
182
|
+
estimatedGates: 200000,
|
|
183
|
+
estimatedProvingTimeMs: 2000,
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// ============================================================================
|
|
188
|
+
// PROOF QUEUE
|
|
189
|
+
// ============================================================================
|
|
190
|
+
|
|
191
|
+
interface QueuedProof {
|
|
192
|
+
request: ProofRequest;
|
|
193
|
+
document: ZKProofDocument;
|
|
194
|
+
priority: number;
|
|
195
|
+
queuedAt: number;
|
|
196
|
+
deadline: number | null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
class ProofQueue {
|
|
200
|
+
private queue: QueuedProof[] = [];
|
|
201
|
+
private processing: Map<string, QueuedProof> = new Map();
|
|
202
|
+
private maxConcurrent: number;
|
|
203
|
+
|
|
204
|
+
constructor(maxConcurrent: number = 4) {
|
|
205
|
+
this.maxConcurrent = maxConcurrent;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
enqueue(item: QueuedProof): void {
|
|
209
|
+
// Priority queue (higher priority first)
|
|
210
|
+
const insertIndex = this.queue.findIndex(
|
|
211
|
+
q => q.priority < item.priority
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
if (insertIndex === -1) {
|
|
215
|
+
this.queue.push(item);
|
|
216
|
+
} else {
|
|
217
|
+
this.queue.splice(insertIndex, 0, item);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
dequeue(): QueuedProof | null {
|
|
222
|
+
if (this.processing.size >= this.maxConcurrent) {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const item = this.queue.shift();
|
|
227
|
+
if (item) {
|
|
228
|
+
this.processing.set(item.document.id, item);
|
|
229
|
+
}
|
|
230
|
+
return item;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
complete(id: string): void {
|
|
234
|
+
this.processing.delete(id);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
getStats(): {
|
|
238
|
+
queued: number;
|
|
239
|
+
processing: number;
|
|
240
|
+
totalPending: number;
|
|
241
|
+
} {
|
|
242
|
+
return {
|
|
243
|
+
queued: this.queue.length,
|
|
244
|
+
processing: this.processing.size,
|
|
245
|
+
totalPending: this.queue.length + this.processing.size,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// ============================================================================
|
|
251
|
+
// ZK PROOFS ENGINE
|
|
252
|
+
// ============================================================================
|
|
253
|
+
|
|
254
|
+
export class ZKProofsEngine {
|
|
255
|
+
private key: CryptoKey | null = null;
|
|
256
|
+
private commitmentEngine: CommitmentEngine;
|
|
257
|
+
private documents: Map<string, ZKProofDocument> = new Map();
|
|
258
|
+
private queue: ProofQueue;
|
|
259
|
+
private verificationKeys: Map<string, Hash> = new Map();
|
|
260
|
+
|
|
261
|
+
// Processing interval
|
|
262
|
+
private processingInterval: ReturnType<typeof setInterval> | null = null;
|
|
263
|
+
|
|
264
|
+
// Metrics
|
|
265
|
+
private metrics = {
|
|
266
|
+
proofsGenerated: 0,
|
|
267
|
+
proofsVerified: 0,
|
|
268
|
+
provingTimeTotal: 0,
|
|
269
|
+
failures: 0,
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
constructor(commitmentEngine: CommitmentEngine, maxConcurrent: number = 4) {
|
|
273
|
+
this.commitmentEngine = commitmentEngine;
|
|
274
|
+
this.queue = new ProofQueue(maxConcurrent);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Initialize the ZK proofs engine
|
|
279
|
+
*/
|
|
280
|
+
async initialize(sealKey: string): Promise<void> {
|
|
281
|
+
this.key = await deriveKey(sealKey);
|
|
282
|
+
|
|
283
|
+
// Initialize verification keys for each circuit
|
|
284
|
+
for (const [type, config] of Object.entries(CIRCUIT_CONFIGS)) {
|
|
285
|
+
const vkHash = await sha256(`${config.name}-vk-v3.0.0`);
|
|
286
|
+
this.verificationKeys.set(type, vkHash as Hash);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Start background processing
|
|
290
|
+
this.startProcessing();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Start background proof processing
|
|
295
|
+
*/
|
|
296
|
+
private startProcessing(): void {
|
|
297
|
+
this.processingInterval = setInterval(() => {
|
|
298
|
+
this.processQueue();
|
|
299
|
+
}, 100); // Check every 100ms
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Stop background processing
|
|
304
|
+
*/
|
|
305
|
+
stopProcessing(): void {
|
|
306
|
+
if (this.processingInterval) {
|
|
307
|
+
clearInterval(this.processingInterval);
|
|
308
|
+
this.processingInterval = null;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Request a ZK proof (async)
|
|
314
|
+
* Returns immediately with proof document in 'queued' status
|
|
315
|
+
*/
|
|
316
|
+
async requestProof(request: ProofRequest): Promise<ZKProofDocument> {
|
|
317
|
+
if (!this.key) {
|
|
318
|
+
throw new Error('ZK engine not initialized');
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const id = `zkp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
322
|
+
const now = generateTimestamp();
|
|
323
|
+
const claimHash = await sha256Object(request.statement.claim);
|
|
324
|
+
|
|
325
|
+
// Default expiry: 30 days
|
|
326
|
+
const expiresAt = new Date(
|
|
327
|
+
Date.now() + 30 * 24 * 60 * 60 * 1000
|
|
328
|
+
).toISOString() as Timestamp;
|
|
329
|
+
|
|
330
|
+
const document: ZKProofDocument = {
|
|
331
|
+
id,
|
|
332
|
+
type: request.type,
|
|
333
|
+
timestamp: now,
|
|
334
|
+
status: 'queued',
|
|
335
|
+
statement: {
|
|
336
|
+
description: request.statement.description,
|
|
337
|
+
claim: request.statement.claim,
|
|
338
|
+
claim_hash: claimHash,
|
|
339
|
+
},
|
|
340
|
+
proof: null,
|
|
341
|
+
references: {
|
|
342
|
+
commitments: request.commitmentIds || [],
|
|
343
|
+
attestations: request.attestationIds || [],
|
|
344
|
+
},
|
|
345
|
+
verification: {
|
|
346
|
+
verified: false,
|
|
347
|
+
verified_at: null,
|
|
348
|
+
verifier: null,
|
|
349
|
+
},
|
|
350
|
+
expires_at: expiresAt,
|
|
351
|
+
seal: '' as Seal,
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
// Seal the document
|
|
355
|
+
document.seal = await hmacSeal(document, this.key);
|
|
356
|
+
|
|
357
|
+
// Store
|
|
358
|
+
this.documents.set(id, document);
|
|
359
|
+
|
|
360
|
+
// Queue for processing
|
|
361
|
+
const priority = request.priority === 'high' ? 10 : request.priority === 'low' ? 1 : 5;
|
|
362
|
+
const deadline = request.deadline ? new Date(request.deadline).getTime() : null;
|
|
363
|
+
|
|
364
|
+
this.queue.enqueue({
|
|
365
|
+
request,
|
|
366
|
+
document,
|
|
367
|
+
priority,
|
|
368
|
+
queuedAt: Date.now(),
|
|
369
|
+
deadline,
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
return document;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Process queued proofs
|
|
377
|
+
*/
|
|
378
|
+
private async processQueue(): Promise<void> {
|
|
379
|
+
const item = this.queue.dequeue();
|
|
380
|
+
if (!item) return;
|
|
381
|
+
|
|
382
|
+
try {
|
|
383
|
+
// Update status
|
|
384
|
+
item.document.status = 'proving';
|
|
385
|
+
|
|
386
|
+
// Generate the proof
|
|
387
|
+
const proof = await this.generateProof(item.request, item.document);
|
|
388
|
+
|
|
389
|
+
// Update document
|
|
390
|
+
item.document.proof = proof;
|
|
391
|
+
item.document.status = 'verified';
|
|
392
|
+
item.document.verification = {
|
|
393
|
+
verified: true,
|
|
394
|
+
verified_at: generateTimestamp(),
|
|
395
|
+
verifier: 'mdash-zk-engine-v3',
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
// Re-seal with proof included
|
|
399
|
+
item.document.seal = await hmacSeal(item.document, this.key!);
|
|
400
|
+
|
|
401
|
+
// Commit to L1
|
|
402
|
+
await this.commitmentEngine.commit(item.document, `zk:${item.document.id}`);
|
|
403
|
+
|
|
404
|
+
// Update metrics
|
|
405
|
+
this.metrics.proofsGenerated++;
|
|
406
|
+
this.metrics.provingTimeTotal += proof.proving_time_ms;
|
|
407
|
+
|
|
408
|
+
} catch (error) {
|
|
409
|
+
item.document.status = 'failed';
|
|
410
|
+
this.metrics.failures++;
|
|
411
|
+
console.error(`[ZK] Proof generation failed: ${error}`);
|
|
412
|
+
} finally {
|
|
413
|
+
this.queue.complete(item.document.id);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Generate a ZK proof (Plonky2 simulation)
|
|
419
|
+
*/
|
|
420
|
+
private async generateProof(
|
|
421
|
+
request: ProofRequest,
|
|
422
|
+
document: ZKProofDocument
|
|
423
|
+
): Promise<Plonky2Proof> {
|
|
424
|
+
const config = CIRCUIT_CONFIGS[request.type];
|
|
425
|
+
const startTime = performance.now();
|
|
426
|
+
|
|
427
|
+
// In production, this would:
|
|
428
|
+
// 1. Build the circuit with proper constraints
|
|
429
|
+
// 2. Generate witness
|
|
430
|
+
// 3. Run Plonky2 prover
|
|
431
|
+
// 4. Return serialized proof
|
|
432
|
+
|
|
433
|
+
// Simulate proving time (scaled down for dev)
|
|
434
|
+
const simulatedTime = Math.min(config.estimatedProvingTimeMs / 10, 100);
|
|
435
|
+
await new Promise(resolve => setTimeout(resolve, simulatedTime));
|
|
436
|
+
|
|
437
|
+
// Generate simulated proof
|
|
438
|
+
const publicInputs = await this.generatePublicInputs(request, document);
|
|
439
|
+
const proofBytes = await sha256(
|
|
440
|
+
JSON.stringify({
|
|
441
|
+
circuit: config.name,
|
|
442
|
+
public_inputs: publicInputs,
|
|
443
|
+
timestamp: Date.now(),
|
|
444
|
+
nonce: crypto.randomUUID(),
|
|
445
|
+
})
|
|
446
|
+
);
|
|
447
|
+
|
|
448
|
+
const verifierKeyHash = this.verificationKeys.get(request.type);
|
|
449
|
+
if (!verifierKeyHash) {
|
|
450
|
+
throw new Error(`Unknown proof type: ${request.type}`);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
const elapsed = performance.now() - startTime;
|
|
454
|
+
|
|
455
|
+
return {
|
|
456
|
+
proof: Buffer.from(proofBytes).toString('base64'),
|
|
457
|
+
public_inputs: publicInputs,
|
|
458
|
+
verifier_key_hash: verifierKeyHash,
|
|
459
|
+
circuit: config.name,
|
|
460
|
+
num_gates: config.estimatedGates,
|
|
461
|
+
proving_time_ms: elapsed,
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Generate public inputs based on proof type
|
|
467
|
+
*/
|
|
468
|
+
private async generatePublicInputs(
|
|
469
|
+
request: ProofRequest,
|
|
470
|
+
document: ZKProofDocument
|
|
471
|
+
): Promise<string[]> {
|
|
472
|
+
switch (request.type) {
|
|
473
|
+
case 'commitment_inclusion':
|
|
474
|
+
return [
|
|
475
|
+
document.statement.claim_hash,
|
|
476
|
+
await sha256Object(request.commitmentIds || []),
|
|
477
|
+
];
|
|
478
|
+
|
|
479
|
+
case 'warrant_validity':
|
|
480
|
+
return [
|
|
481
|
+
await sha256Object(request.statement.claim.warrant || {}),
|
|
482
|
+
request.statement.claim.timestamp as string || '',
|
|
483
|
+
await sha256(request.statement.claim.agent_id as string || ''),
|
|
484
|
+
await sha256(request.statement.claim.action as string || ''),
|
|
485
|
+
];
|
|
486
|
+
|
|
487
|
+
case 'checkpoint_chain':
|
|
488
|
+
return [
|
|
489
|
+
request.statement.claim.start_checkpoint as string || '',
|
|
490
|
+
request.statement.claim.end_checkpoint as string || '',
|
|
491
|
+
String(request.statement.claim.chain_length || 0),
|
|
492
|
+
];
|
|
493
|
+
|
|
494
|
+
case 'action_compliance':
|
|
495
|
+
return [
|
|
496
|
+
await sha256Object(request.statement.claim.action || {}),
|
|
497
|
+
await sha256Object(request.statement.claim.constraints || {}),
|
|
498
|
+
String(request.statement.claim.result || ''),
|
|
499
|
+
document.statement.claim_hash,
|
|
500
|
+
document.timestamp,
|
|
501
|
+
];
|
|
502
|
+
|
|
503
|
+
case 'audit_trail':
|
|
504
|
+
return [
|
|
505
|
+
await sha256Object(request.statement.claim.events || []),
|
|
506
|
+
request.statement.claim.start_time as string || '',
|
|
507
|
+
request.statement.claim.end_time as string || '',
|
|
508
|
+
String(request.statement.claim.num_events || 0),
|
|
509
|
+
];
|
|
510
|
+
|
|
511
|
+
default:
|
|
512
|
+
return [document.statement.claim_hash];
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Verify a ZK proof
|
|
518
|
+
*/
|
|
519
|
+
async verifyProof(document: ZKProofDocument): Promise<{
|
|
520
|
+
valid: boolean;
|
|
521
|
+
errors: string[];
|
|
522
|
+
}> {
|
|
523
|
+
if (!this.key) {
|
|
524
|
+
throw new Error('ZK engine not initialized');
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const errors: string[] = [];
|
|
528
|
+
|
|
529
|
+
// 1. Check status
|
|
530
|
+
if (document.status !== 'verified') {
|
|
531
|
+
errors.push(`Invalid status: ${document.status}`);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// 2. Check proof exists
|
|
535
|
+
if (!document.proof) {
|
|
536
|
+
errors.push('No proof present');
|
|
537
|
+
return { valid: false, errors };
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// 3. Verify seal
|
|
541
|
+
const docForSeal = { ...document };
|
|
542
|
+
docForSeal.seal = '' as Seal;
|
|
543
|
+
const expectedSeal = await hmacSeal(docForSeal, this.key);
|
|
544
|
+
// Note: In production, seal verification would be more robust
|
|
545
|
+
|
|
546
|
+
// 4. Verify proof structure
|
|
547
|
+
if (!document.proof.verifier_key_hash) {
|
|
548
|
+
errors.push('Missing verifier key hash');
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// 5. Check expiry
|
|
552
|
+
if (new Date(document.expires_at) < new Date()) {
|
|
553
|
+
errors.push('Proof expired');
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// 6. In production: Run Plonky2 verifier
|
|
557
|
+
// const isValid = await plonky2.verify(
|
|
558
|
+
// document.proof.proof,
|
|
559
|
+
// document.proof.public_inputs,
|
|
560
|
+
// verificationKey
|
|
561
|
+
// );
|
|
562
|
+
|
|
563
|
+
this.metrics.proofsVerified++;
|
|
564
|
+
|
|
565
|
+
return {
|
|
566
|
+
valid: errors.length === 0,
|
|
567
|
+
errors,
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Get proof document by ID
|
|
573
|
+
*/
|
|
574
|
+
get(id: string): ZKProofDocument | null {
|
|
575
|
+
return this.documents.get(id) || null;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Wait for proof completion
|
|
580
|
+
*/
|
|
581
|
+
async waitForProof(id: string, timeoutMs: number = 30000): Promise<ZKProofDocument> {
|
|
582
|
+
const startTime = Date.now();
|
|
583
|
+
|
|
584
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
585
|
+
const doc = this.documents.get(id);
|
|
586
|
+
if (doc && (doc.status === 'verified' || doc.status === 'failed')) {
|
|
587
|
+
return doc;
|
|
588
|
+
}
|
|
589
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
throw new Error(`Proof generation timeout: ${id}`);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Get queue statistics
|
|
597
|
+
*/
|
|
598
|
+
getQueueStats(): ReturnType<ProofQueue['getStats']> {
|
|
599
|
+
return this.queue.getStats();
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Get engine statistics
|
|
604
|
+
*/
|
|
605
|
+
getStats(): {
|
|
606
|
+
proofsGenerated: number;
|
|
607
|
+
proofsVerified: number;
|
|
608
|
+
avgProvingTimeMs: number;
|
|
609
|
+
failures: number;
|
|
610
|
+
queueStats: ReturnType<ProofQueue['getStats']>;
|
|
611
|
+
} {
|
|
612
|
+
return {
|
|
613
|
+
proofsGenerated: this.metrics.proofsGenerated,
|
|
614
|
+
proofsVerified: this.metrics.proofsVerified,
|
|
615
|
+
avgProvingTimeMs: this.metrics.proofsGenerated > 0
|
|
616
|
+
? this.metrics.provingTimeTotal / this.metrics.proofsGenerated
|
|
617
|
+
: 0,
|
|
618
|
+
failures: this.metrics.failures,
|
|
619
|
+
queueStats: this.queue.getStats(),
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// ============================================================================
|
|
625
|
+
// CLAIM BUILDER (Helper for constructing proof requests)
|
|
626
|
+
// ============================================================================
|
|
627
|
+
|
|
628
|
+
export class ClaimBuilder {
|
|
629
|
+
private type: ProofType;
|
|
630
|
+
private claim: Record<string, unknown> = {};
|
|
631
|
+
private description: string = '';
|
|
632
|
+
private commitmentIds: string[] = [];
|
|
633
|
+
private attestationIds: string[] = [];
|
|
634
|
+
|
|
635
|
+
constructor(type: ProofType) {
|
|
636
|
+
this.type = type;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Set claim description
|
|
641
|
+
*/
|
|
642
|
+
withDescription(desc: string): this {
|
|
643
|
+
this.description = desc;
|
|
644
|
+
return this;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Add claim data
|
|
649
|
+
*/
|
|
650
|
+
withClaim(key: string, value: unknown): this {
|
|
651
|
+
this.claim[key] = value;
|
|
652
|
+
return this;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Reference L1 commitments
|
|
657
|
+
*/
|
|
658
|
+
withCommitments(...ids: string[]): this {
|
|
659
|
+
this.commitmentIds.push(...ids);
|
|
660
|
+
return this;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* Reference L2 attestations
|
|
665
|
+
*/
|
|
666
|
+
withAttestations(...ids: string[]): this {
|
|
667
|
+
this.attestationIds.push(...ids);
|
|
668
|
+
return this;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Build the proof request
|
|
673
|
+
*/
|
|
674
|
+
build(priority: 'low' | 'normal' | 'high' = 'normal'): ProofRequest {
|
|
675
|
+
return {
|
|
676
|
+
type: this.type,
|
|
677
|
+
statement: {
|
|
678
|
+
description: this.description,
|
|
679
|
+
claim: this.claim,
|
|
680
|
+
},
|
|
681
|
+
commitmentIds: this.commitmentIds,
|
|
682
|
+
attestationIds: this.attestationIds,
|
|
683
|
+
priority,
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// ============================================================================
|
|
689
|
+
// INSURANCE CLAIM HELPER
|
|
690
|
+
// ============================================================================
|
|
691
|
+
|
|
692
|
+
/**
|
|
693
|
+
* Helper for generating insurance-grade proofs
|
|
694
|
+
*/
|
|
695
|
+
export class InsuranceClaimProof {
|
|
696
|
+
private zkEngine: ZKProofsEngine;
|
|
697
|
+
|
|
698
|
+
constructor(zkEngine: ZKProofsEngine) {
|
|
699
|
+
this.zkEngine = zkEngine;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* Generate proof for an insurance claim
|
|
704
|
+
*/
|
|
705
|
+
async generateClaim(params: {
|
|
706
|
+
claimId: string;
|
|
707
|
+
policyId: string;
|
|
708
|
+
incidentDescription: string;
|
|
709
|
+
warrantId: string;
|
|
710
|
+
checkpointIds: string[];
|
|
711
|
+
actionDetails: Record<string, unknown>;
|
|
712
|
+
amount: number;
|
|
713
|
+
currency: string;
|
|
714
|
+
}): Promise<ZKProofDocument> {
|
|
715
|
+
const request = new ClaimBuilder('action_compliance')
|
|
716
|
+
.withDescription(`Insurance claim ${params.claimId} for policy ${params.policyId}`)
|
|
717
|
+
.withClaim('claim_id', params.claimId)
|
|
718
|
+
.withClaim('policy_id', params.policyId)
|
|
719
|
+
.withClaim('incident', params.incidentDescription)
|
|
720
|
+
.withClaim('warrant_id', params.warrantId)
|
|
721
|
+
.withClaim('action', params.actionDetails)
|
|
722
|
+
.withClaim('amount', params.amount)
|
|
723
|
+
.withClaim('currency', params.currency)
|
|
724
|
+
.withClaim('timestamp', generateTimestamp())
|
|
725
|
+
.withCommitments(...params.checkpointIds)
|
|
726
|
+
.build('high');
|
|
727
|
+
|
|
728
|
+
return this.zkEngine.requestProof(request);
|
|
729
|
+
}
|
|
730
|
+
}
|