@cofhe/sdk 0.1.1 → 0.2.1
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/CHANGELOG.md +22 -0
- package/adapters/ethers6.ts +28 -28
- package/adapters/hardhat.ts +0 -1
- package/adapters/index.test.ts +14 -19
- package/adapters/smartWallet.ts +81 -73
- package/adapters/test-utils.ts +45 -45
- package/adapters/types.ts +3 -3
- package/chains/chains/localcofhe.ts +14 -0
- package/chains/chains.test.ts +2 -1
- package/chains/defineChain.ts +2 -2
- package/chains/index.ts +3 -1
- package/chains/types.ts +3 -3
- package/core/baseBuilder.ts +30 -49
- package/core/client.test.ts +200 -72
- package/core/client.ts +152 -148
- package/core/clientTypes.ts +114 -0
- package/core/config.test.ts +30 -11
- package/core/config.ts +26 -13
- package/core/consts.ts +18 -0
- package/core/decrypt/cofheMocksSealOutput.ts +2 -4
- package/core/decrypt/decryptHandleBuilder.ts +51 -45
- package/core/decrypt/{tnSealOutput.ts → tnSealOutputV1.ts} +1 -1
- package/core/decrypt/tnSealOutputV2.ts +298 -0
- package/core/encrypt/cofheMocksZkVerifySign.ts +15 -16
- package/core/encrypt/encryptInputsBuilder.test.ts +132 -116
- package/core/encrypt/encryptInputsBuilder.ts +159 -111
- package/core/encrypt/encryptUtils.ts +6 -3
- package/core/encrypt/zkPackProveVerify.ts +70 -8
- package/core/error.ts +0 -2
- package/core/fetchKeys.test.ts +1 -18
- package/core/fetchKeys.ts +0 -26
- package/core/index.ts +37 -17
- package/core/keyStore.ts +65 -38
- package/core/permits.test.ts +255 -4
- package/core/permits.ts +83 -18
- package/core/types.ts +198 -152
- package/core/utils.ts +43 -1
- package/dist/adapters.d.cts +38 -20
- package/dist/adapters.d.ts +38 -20
- package/dist/chains.cjs +18 -8
- package/dist/chains.d.cts +31 -9
- package/dist/chains.d.ts +31 -9
- package/dist/chains.js +1 -1
- package/dist/{chunk-KFGPTJ6X.js → chunk-I5WFEYXX.js} +1768 -1526
- package/dist/{chunk-LU7BMUUT.js → chunk-R3B5TMVX.js} +330 -197
- package/dist/{chunk-GZCQQYVI.js → chunk-TBLR7NNE.js} +18 -9
- package/dist/{types-PhwGgQvs.d.ts → clientTypes-RqkgkV2i.d.ts} +331 -429
- package/dist/{types-bB7wLj0q.d.cts → clientTypes-e4filDzK.d.cts} +331 -429
- package/dist/core.cjs +3000 -2625
- package/dist/core.d.cts +113 -7
- package/dist/core.d.ts +113 -7
- package/dist/core.js +3 -3
- package/dist/node.cjs +2851 -2526
- package/dist/node.d.cts +4 -4
- package/dist/node.d.ts +4 -4
- package/dist/node.js +4 -3
- package/dist/{permit-S9CnI6MF.d.cts → permit-MZ502UBl.d.cts} +54 -41
- package/dist/{permit-S9CnI6MF.d.ts → permit-MZ502UBl.d.ts} +54 -41
- package/dist/permits.cjs +328 -195
- package/dist/permits.d.cts +113 -825
- package/dist/permits.d.ts +113 -825
- package/dist/permits.js +1 -1
- package/dist/types-YiAC4gig.d.cts +33 -0
- package/dist/types-YiAC4gig.d.ts +33 -0
- package/dist/web.cjs +3067 -2527
- package/dist/web.d.cts +22 -6
- package/dist/web.d.ts +22 -6
- package/dist/web.js +185 -9
- package/dist/zkProve.worker.cjs +93 -0
- package/dist/zkProve.worker.d.cts +2 -0
- package/dist/zkProve.worker.d.ts +2 -0
- package/dist/zkProve.worker.js +91 -0
- package/node/client.test.ts +20 -25
- package/node/encryptInputs.test.ts +18 -38
- package/node/index.ts +1 -0
- package/package.json +15 -15
- package/permits/index.ts +1 -0
- package/permits/localstorage.test.ts +9 -14
- package/permits/onchain-utils.ts +221 -0
- package/permits/permit.test.ts +76 -27
- package/permits/permit.ts +58 -95
- package/permits/sealing.test.ts +3 -3
- package/permits/sealing.ts +2 -2
- package/permits/store.test.ts +10 -50
- package/permits/store.ts +9 -21
- package/permits/test-utils.ts +11 -3
- package/permits/types.ts +39 -9
- package/permits/utils.ts +0 -5
- package/permits/validation.test.ts +29 -32
- package/permits/validation.ts +114 -176
- package/web/client.web.test.ts +20 -25
- package/web/config.web.test.ts +0 -2
- package/web/encryptInputs.web.test.ts +31 -54
- package/web/index.ts +65 -1
- package/web/storage.ts +19 -5
- package/web/worker.builder.web.test.ts +148 -0
- package/web/worker.config.web.test.ts +329 -0
- package/web/worker.output.web.test.ts +84 -0
- package/web/workerManager.test.ts +80 -0
- package/web/workerManager.ts +214 -0
- package/web/workerManager.web.test.ts +114 -0
- package/web/zkProve.worker.ts +133 -0
- package/core/result.test.ts +0 -180
- package/core/result.ts +0 -67
- package/core/test-utils.ts +0 -45
- package/dist/types-KImPrEIe.d.cts +0 -48
- package/dist/types-KImPrEIe.d.ts +0 -48
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
type ZkBuilderAndCrsGenerator,
|
|
3
|
+
type ZkProveWorkerFunction,
|
|
4
|
+
zkPack,
|
|
5
|
+
zkProve,
|
|
6
|
+
zkProveWithWorker,
|
|
7
|
+
zkVerify,
|
|
8
|
+
constructZkPoKMetadata,
|
|
9
|
+
} from './zkPackProveVerify.js';
|
|
4
10
|
import { CofhesdkError, CofhesdkErrorCode } from '../error.js';
|
|
5
|
-
import { type Result, resultWrapper } from '../result.js';
|
|
6
11
|
import {
|
|
7
12
|
type EncryptStepCallbackFunction,
|
|
8
13
|
EncryptStep,
|
|
@@ -31,6 +36,7 @@ type EncryptInputsBuilderParams<T extends EncryptableItem[]> = BaseBuilderParams
|
|
|
31
36
|
compactPkeCrsDeserializer: FheKeyDeserializer | undefined;
|
|
32
37
|
zkBuilderAndCrsGenerator: ZkBuilderAndCrsGenerator | undefined;
|
|
33
38
|
initTfhe: TfheInitializer | undefined;
|
|
39
|
+
zkProveWorkerFn: ZkProveWorkerFunction | undefined;
|
|
34
40
|
|
|
35
41
|
keysStorage: KeysStorage | undefined;
|
|
36
42
|
};
|
|
@@ -39,9 +45,6 @@ type EncryptInputsBuilderParams<T extends EncryptableItem[]> = BaseBuilderParams
|
|
|
39
45
|
* EncryptInputsBuilder exposes a builder pattern for encrypting inputs.
|
|
40
46
|
* account, securityZone, and chainId can be overridden in the builder.
|
|
41
47
|
* config, tfhePublicKeyDeserializer, compactPkeCrsDeserializer, and zkBuilderAndCrsGenerator are required to be set in the builder.
|
|
42
|
-
*
|
|
43
|
-
* @dev All errors must be throw in `encrypt`, which wraps them in a Result.
|
|
44
|
-
* Do not throw errors in the constructor or in the builder methods.
|
|
45
48
|
*/
|
|
46
49
|
|
|
47
50
|
export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuilder {
|
|
@@ -51,13 +54,17 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
51
54
|
|
|
52
55
|
private zkvWalletClient: WalletClient | undefined;
|
|
53
56
|
|
|
54
|
-
private tfhePublicKeyDeserializer: FheKeyDeserializer
|
|
55
|
-
private compactPkeCrsDeserializer: FheKeyDeserializer
|
|
56
|
-
private zkBuilderAndCrsGenerator: ZkBuilderAndCrsGenerator
|
|
57
|
+
private tfhePublicKeyDeserializer: FheKeyDeserializer;
|
|
58
|
+
private compactPkeCrsDeserializer: FheKeyDeserializer;
|
|
59
|
+
private zkBuilderAndCrsGenerator: ZkBuilderAndCrsGenerator;
|
|
57
60
|
private initTfhe: TfheInitializer | undefined;
|
|
61
|
+
private zkProveWorkerFn: ZkProveWorkerFunction | undefined;
|
|
58
62
|
|
|
59
63
|
private keysStorage: KeysStorage | undefined;
|
|
60
64
|
|
|
65
|
+
// Worker configuration (from config, overrideable)
|
|
66
|
+
private useWorker: boolean;
|
|
67
|
+
|
|
61
68
|
private stepTimestamps: Record<EncryptStep, number> = {
|
|
62
69
|
[EncryptStep.InitTfhe]: 0,
|
|
63
70
|
[EncryptStep.FetchKeys]: 0,
|
|
@@ -81,12 +88,56 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
81
88
|
|
|
82
89
|
this.zkvWalletClient = params.zkvWalletClient;
|
|
83
90
|
|
|
91
|
+
// Check that tfhePublicKeyDeserializer is provided
|
|
92
|
+
if (!params.tfhePublicKeyDeserializer) {
|
|
93
|
+
throw new CofhesdkError({
|
|
94
|
+
code: CofhesdkErrorCode.MissingTfhePublicKeyDeserializer,
|
|
95
|
+
message: 'EncryptInputsBuilder tfhePublicKeyDeserializer is undefined',
|
|
96
|
+
hint: 'Ensure client has been created with a tfhePublicKeyDeserializer.',
|
|
97
|
+
context: {
|
|
98
|
+
tfhePublicKeyDeserializer: params.tfhePublicKeyDeserializer,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
84
102
|
this.tfhePublicKeyDeserializer = params.tfhePublicKeyDeserializer;
|
|
103
|
+
|
|
104
|
+
// Check that compactPkeCrsDeserializer is provided
|
|
105
|
+
if (!params.compactPkeCrsDeserializer) {
|
|
106
|
+
throw new CofhesdkError({
|
|
107
|
+
code: CofhesdkErrorCode.MissingCompactPkeCrsDeserializer,
|
|
108
|
+
message: 'EncryptInputsBuilder compactPkeCrsDeserializer is undefined',
|
|
109
|
+
hint: 'Ensure client has been created with a compactPkeCrsDeserializer.',
|
|
110
|
+
context: {
|
|
111
|
+
compactPkeCrsDeserializer: params.compactPkeCrsDeserializer,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
}
|
|
85
115
|
this.compactPkeCrsDeserializer = params.compactPkeCrsDeserializer;
|
|
116
|
+
|
|
117
|
+
// Check that zkBuilderAndCrsGenerator is provided
|
|
118
|
+
if (!params.zkBuilderAndCrsGenerator) {
|
|
119
|
+
throw new CofhesdkError({
|
|
120
|
+
code: CofhesdkErrorCode.MissingZkBuilderAndCrsGenerator,
|
|
121
|
+
message: 'EncryptInputsBuilder zkBuilderAndCrsGenerator is undefined',
|
|
122
|
+
hint: 'Ensure client has been created with a zkBuilderAndCrsGenerator.',
|
|
123
|
+
context: {
|
|
124
|
+
zkBuilderAndCrsGenerator: params.zkBuilderAndCrsGenerator,
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
}
|
|
86
128
|
this.zkBuilderAndCrsGenerator = params.zkBuilderAndCrsGenerator;
|
|
129
|
+
|
|
130
|
+
// Optional tfhe initialization function, will be run if provided
|
|
87
131
|
this.initTfhe = params.initTfhe;
|
|
88
132
|
|
|
133
|
+
// Optional zkProve worker function, will be used on web if useWorkers is true and worker function is provided
|
|
134
|
+
this.zkProveWorkerFn = params.zkProveWorkerFn;
|
|
135
|
+
|
|
136
|
+
// Keys storage is used to store the FHE key and CRS
|
|
89
137
|
this.keysStorage = params.keysStorage;
|
|
138
|
+
|
|
139
|
+
// Initialize useWorker from config (can be overridden via setUseWorker) - default to true
|
|
140
|
+
this.useWorker = params.config?.useWorkers ?? true;
|
|
90
141
|
}
|
|
91
142
|
|
|
92
143
|
/**
|
|
@@ -158,6 +209,42 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
158
209
|
return this.securityZone;
|
|
159
210
|
}
|
|
160
211
|
|
|
212
|
+
/**
|
|
213
|
+
* @param useWorker - Whether to use Web Workers for ZK proof generation.
|
|
214
|
+
*
|
|
215
|
+
* Overrides the config-level useWorkers setting for this specific encryption.
|
|
216
|
+
*
|
|
217
|
+
* Example:
|
|
218
|
+
* ```typescript
|
|
219
|
+
* const encrypted = await encryptInputs([Encryptable.uint128(10n)])
|
|
220
|
+
* .setUseWorker(false)
|
|
221
|
+
* .encrypt();
|
|
222
|
+
* ```
|
|
223
|
+
*
|
|
224
|
+
* @returns The chainable EncryptInputsBuilder instance.
|
|
225
|
+
*/
|
|
226
|
+
setUseWorker(useWorker: boolean): EncryptInputsBuilder<T> {
|
|
227
|
+
this.useWorker = useWorker;
|
|
228
|
+
return this;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Gets the current worker configuration.
|
|
233
|
+
*
|
|
234
|
+
* @returns Whether Web Workers are enabled for this encryption.
|
|
235
|
+
*
|
|
236
|
+
* Example:
|
|
237
|
+
* ```typescript
|
|
238
|
+
* const builder = encryptInputs([Encryptable.uint128(10n)]);
|
|
239
|
+
* console.log(builder.getUseWorker()); // true (from config)
|
|
240
|
+
* builder.setUseWorker(false);
|
|
241
|
+
* console.log(builder.getUseWorker()); // false (overridden)
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
getUseWorker(): boolean {
|
|
245
|
+
return this.useWorker;
|
|
246
|
+
}
|
|
247
|
+
|
|
161
248
|
/**
|
|
162
249
|
* @param callback - Function to be called with the encryption step.
|
|
163
250
|
*
|
|
@@ -202,50 +289,13 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
202
289
|
this.stepCallback(step, { ...context, isStart: false, isEnd: true, duration });
|
|
203
290
|
}
|
|
204
291
|
|
|
205
|
-
/**
|
|
206
|
-
* tfhePublicKeyDeserializer is a platform-specific dependency injected into core/createCofhesdkClientBase by web/createCofhesdkClient and node/createCofhesdkClient
|
|
207
|
-
* web/ uses zama "tfhe"
|
|
208
|
-
* node/ uses zama "node-tfhe"
|
|
209
|
-
* Users should not set this manually.
|
|
210
|
-
*/
|
|
211
|
-
private getTfhePublicKeyDeserializerOrThrow(): FheKeyDeserializer {
|
|
212
|
-
if (this.tfhePublicKeyDeserializer) return this.tfhePublicKeyDeserializer;
|
|
213
|
-
throw new CofhesdkError({
|
|
214
|
-
code: CofhesdkErrorCode.MissingTfhePublicKeyDeserializer,
|
|
215
|
-
message: 'EncryptInputsBuilder tfhePublicKeyDeserializer is undefined',
|
|
216
|
-
hint: 'Ensure client has been created with a tfhePublicKeyDeserializer.',
|
|
217
|
-
context: {
|
|
218
|
-
tfhePublicKeyDeserializer: this.tfhePublicKeyDeserializer,
|
|
219
|
-
},
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* compactPkeCrsDeserializer is a platform-specific dependency injected into core/createCofhesdkClientBase by web/createCofhesdkClient and node/createCofhesdkClient
|
|
225
|
-
* web/ uses zama "tfhe"
|
|
226
|
-
* node/ uses zama "node-tfhe"
|
|
227
|
-
* Users should not set this manually.
|
|
228
|
-
*/
|
|
229
|
-
private getCompactPkeCrsDeserializerOrThrow(): FheKeyDeserializer {
|
|
230
|
-
if (this.compactPkeCrsDeserializer) return this.compactPkeCrsDeserializer;
|
|
231
|
-
throw new CofhesdkError({
|
|
232
|
-
code: CofhesdkErrorCode.MissingCompactPkeCrsDeserializer,
|
|
233
|
-
message: 'EncryptInputsBuilder compactPkeCrsDeserializer is undefined',
|
|
234
|
-
hint: 'Ensure client has been created with a compactPkeCrsDeserializer.',
|
|
235
|
-
context: {
|
|
236
|
-
compactPkeCrsDeserializer: this.compactPkeCrsDeserializer,
|
|
237
|
-
},
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
|
|
241
292
|
/**
|
|
242
293
|
* zkVerifierUrl is included in the chains exported from cofhesdk/chains for use in CofhesdkConfig.supportedChains
|
|
243
294
|
* Users should generally not set this manually.
|
|
244
295
|
*/
|
|
245
296
|
private async getZkVerifierUrl(): Promise<string> {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
return getZkVerifierUrlOrThrow(config, chainId);
|
|
297
|
+
this.assertChainId();
|
|
298
|
+
return getZkVerifierUrlOrThrow(this.config, this.chainId);
|
|
249
299
|
}
|
|
250
300
|
|
|
251
301
|
/**
|
|
@@ -280,10 +330,7 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
280
330
|
crs: string;
|
|
281
331
|
crsFetchedFromCoFHE: boolean;
|
|
282
332
|
}> {
|
|
283
|
-
|
|
284
|
-
const chainId = await this.getChainIdOrThrow();
|
|
285
|
-
const compactPkeCrsDeserializer = this.getCompactPkeCrsDeserializerOrThrow();
|
|
286
|
-
const tfhePublicKeyDeserializer = this.getTfhePublicKeyDeserializerOrThrow();
|
|
333
|
+
this.assertChainId();
|
|
287
334
|
const securityZone = this.getSecurityZone();
|
|
288
335
|
|
|
289
336
|
try {
|
|
@@ -305,11 +352,11 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
305
352
|
|
|
306
353
|
try {
|
|
307
354
|
[[fheKey, fheKeyFetchedFromCoFHE], [crs, crsFetchedFromCoFHE]] = await fetchKeys(
|
|
308
|
-
config,
|
|
309
|
-
chainId,
|
|
355
|
+
this.config,
|
|
356
|
+
this.chainId,
|
|
310
357
|
securityZone,
|
|
311
|
-
tfhePublicKeyDeserializer,
|
|
312
|
-
compactPkeCrsDeserializer,
|
|
358
|
+
this.tfhePublicKeyDeserializer,
|
|
359
|
+
this.compactPkeCrsDeserializer,
|
|
313
360
|
this.keysStorage
|
|
314
361
|
);
|
|
315
362
|
} catch (error) {
|
|
@@ -317,11 +364,11 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
317
364
|
code: CofhesdkErrorCode.FetchKeysFailed,
|
|
318
365
|
message: `Failed to fetch FHE key and CRS`,
|
|
319
366
|
context: {
|
|
320
|
-
config,
|
|
321
|
-
chainId,
|
|
367
|
+
config: this.config,
|
|
368
|
+
chainId: this.chainId,
|
|
322
369
|
securityZone,
|
|
323
|
-
compactPkeCrsDeserializer,
|
|
324
|
-
tfhePublicKeyDeserializer,
|
|
370
|
+
compactPkeCrsDeserializer: this.compactPkeCrsDeserializer,
|
|
371
|
+
tfhePublicKeyDeserializer: this.tfhePublicKeyDeserializer,
|
|
325
372
|
},
|
|
326
373
|
});
|
|
327
374
|
}
|
|
@@ -331,7 +378,7 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
331
378
|
code: CofhesdkErrorCode.MissingFheKey,
|
|
332
379
|
message: `FHE key not found`,
|
|
333
380
|
context: {
|
|
334
|
-
chainId,
|
|
381
|
+
chainId: this.chainId,
|
|
335
382
|
securityZone,
|
|
336
383
|
},
|
|
337
384
|
});
|
|
@@ -342,7 +389,7 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
342
389
|
code: CofhesdkErrorCode.MissingCrs,
|
|
343
390
|
message: `CRS not found for chainId <${this.chainId}>`,
|
|
344
391
|
context: {
|
|
345
|
-
chainId,
|
|
392
|
+
chainId: this.chainId,
|
|
346
393
|
},
|
|
347
394
|
});
|
|
348
395
|
}
|
|
@@ -350,31 +397,6 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
350
397
|
return { fheKey, fheKeyFetchedFromCoFHE, crs, crsFetchedFromCoFHE };
|
|
351
398
|
}
|
|
352
399
|
|
|
353
|
-
/**
|
|
354
|
-
* zkBuilderAndCrsGenerator is a platform-specific dependency injected into core/createCofhesdkClientBase by web/createCofhesdkClient and node/createCofhesdkClient
|
|
355
|
-
* web/ uses zama "tfhe"
|
|
356
|
-
* node/ uses zama "node-tfhe"
|
|
357
|
-
* Users should not set this manually.
|
|
358
|
-
*
|
|
359
|
-
* Generates the zkBuilder and zkCrs from the fheKey and crs
|
|
360
|
-
*/
|
|
361
|
-
private generateZkBuilderAndCrs(fheKey: string, crs: string) {
|
|
362
|
-
const zkBuilderAndCrsGenerator = this.zkBuilderAndCrsGenerator;
|
|
363
|
-
|
|
364
|
-
if (!zkBuilderAndCrsGenerator) {
|
|
365
|
-
throw new CofhesdkError({
|
|
366
|
-
code: CofhesdkErrorCode.MissingZkBuilderAndCrsGenerator,
|
|
367
|
-
message: `zkBuilderAndCrsGenerator is undefined`,
|
|
368
|
-
hint: 'Ensure client has been created with a zkBuilderAndCrsGenerator.',
|
|
369
|
-
context: {
|
|
370
|
-
zkBuilderAndCrsGenerator: this.zkBuilderAndCrsGenerator,
|
|
371
|
-
},
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
return zkBuilderAndCrsGenerator(fheKey, crs);
|
|
376
|
-
}
|
|
377
|
-
|
|
378
400
|
/**
|
|
379
401
|
* @dev Encrypt against the cofheMocks instead of CoFHE
|
|
380
402
|
*
|
|
@@ -382,7 +404,11 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
382
404
|
* cofheMocksInsertPackedHashes - stores the ctHashes and their plaintext values for on-chain mocking of FHE operations.
|
|
383
405
|
* cofheMocksZkCreateProofSignatures - creates signatures to be included in the encrypted inputs. The signers address is known and verified in the mock contracts.
|
|
384
406
|
*/
|
|
385
|
-
private async mocksEncrypt(
|
|
407
|
+
private async mocksEncrypt(): Promise<[...EncryptedItemInputs<T>]> {
|
|
408
|
+
this.assertAccount();
|
|
409
|
+
this.assertPublicClient();
|
|
410
|
+
this.assertWalletClient();
|
|
411
|
+
|
|
386
412
|
this.fireStepStart(EncryptStep.InitTfhe);
|
|
387
413
|
await sleep(100);
|
|
388
414
|
this.fireStepEnd(EncryptStep.InitTfhe, { tfheInitializationExecuted: false });
|
|
@@ -404,10 +430,10 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
404
430
|
await sleep(500);
|
|
405
431
|
const signedResults = await cofheMocksZkVerifySign(
|
|
406
432
|
this.inputItems,
|
|
407
|
-
account,
|
|
433
|
+
this.account,
|
|
408
434
|
this.securityZone,
|
|
409
|
-
this.
|
|
410
|
-
this.
|
|
435
|
+
this.publicClient,
|
|
436
|
+
this.walletClient,
|
|
411
437
|
this.zkvWalletClient
|
|
412
438
|
);
|
|
413
439
|
const encryptedInputs: EncryptedItemInput[] = signedResults.map(({ ct_hash, signature }, index) => ({
|
|
@@ -424,7 +450,10 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
424
450
|
/**
|
|
425
451
|
* In the production context, perform a true encryption with the CoFHE coprocessor.
|
|
426
452
|
*/
|
|
427
|
-
private async productionEncrypt(
|
|
453
|
+
private async productionEncrypt(): Promise<[...EncryptedItemInputs<T>]> {
|
|
454
|
+
this.assertAccount();
|
|
455
|
+
this.assertChainId();
|
|
456
|
+
|
|
428
457
|
this.fireStepStart(EncryptStep.InitTfhe);
|
|
429
458
|
|
|
430
459
|
// Deferred initialization of tfhe wasm until encrypt is called
|
|
@@ -438,7 +467,8 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
438
467
|
// Deferred fetching of fheKey and crs until encrypt is called
|
|
439
468
|
// if the key/crs is already in the store, it is not fetched from the CoFHE API
|
|
440
469
|
const { fheKey, fheKeyFetchedFromCoFHE, crs, crsFetchedFromCoFHE } = await this.fetchFheKeyAndCrs();
|
|
441
|
-
|
|
470
|
+
|
|
471
|
+
let { zkBuilder, zkCrs } = this.zkBuilderAndCrsGenerator(fheKey, crs);
|
|
442
472
|
|
|
443
473
|
this.fireStepEnd(EncryptStep.FetchKeys, { fheKeyFetchedFromCoFHE, crsFetchedFromCoFHE });
|
|
444
474
|
|
|
@@ -450,15 +480,42 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
450
480
|
|
|
451
481
|
this.fireStepStart(EncryptStep.Prove);
|
|
452
482
|
|
|
453
|
-
|
|
483
|
+
// Construct metadata once (used by both worker and main thread paths)
|
|
484
|
+
const metadata = constructZkPoKMetadata(this.account, this.securityZone, this.chainId);
|
|
485
|
+
|
|
486
|
+
let proof: Uint8Array | null = null;
|
|
487
|
+
let usedWorker = false;
|
|
488
|
+
let workerFailedError: string | undefined;
|
|
489
|
+
|
|
490
|
+
// Decision logic: try worker if enabled and available, fallback to main thread
|
|
491
|
+
if (this.useWorker && this.zkProveWorkerFn) {
|
|
492
|
+
try {
|
|
493
|
+
// Call worker function directly (no packing needed, worker does it)
|
|
494
|
+
proof = await zkProveWithWorker(this.zkProveWorkerFn, fheKey, crs, this.inputItems, metadata);
|
|
495
|
+
usedWorker = true;
|
|
496
|
+
} catch (error) {
|
|
497
|
+
// Worker failed - capture error for debugging
|
|
498
|
+
workerFailedError = error instanceof Error ? error.message : String(error);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
454
501
|
|
|
455
|
-
|
|
502
|
+
if (proof == null) {
|
|
503
|
+
// Use main thread directly (workers disabled or unavailable)
|
|
504
|
+
proof = await zkProve(zkBuilder, zkCrs, metadata);
|
|
505
|
+
usedWorker = false;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
this.fireStepEnd(EncryptStep.Prove, {
|
|
509
|
+
useWorker: this.useWorker,
|
|
510
|
+
usedWorker,
|
|
511
|
+
workerFailedError,
|
|
512
|
+
});
|
|
456
513
|
|
|
457
514
|
this.fireStepStart(EncryptStep.Verify);
|
|
458
515
|
|
|
459
516
|
const zkVerifierUrl = await this.getZkVerifierUrl();
|
|
460
517
|
|
|
461
|
-
const verifyResults = await zkVerify(zkVerifierUrl, proof, account, this.securityZone, chainId);
|
|
518
|
+
const verifyResults = await zkVerify(zkVerifierUrl, proof, this.account, this.securityZone, this.chainId);
|
|
462
519
|
// Add securityZone and utype to the verify results
|
|
463
520
|
const encryptedInputs: EncryptedItemInput[] = verifyResults.map(
|
|
464
521
|
({ ct_hash, signature }: { ct_hash: string; signature: string }, index: number) => ({
|
|
@@ -493,20 +550,11 @@ export class EncryptInputsBuilder<T extends EncryptableItem[]> extends BaseBuild
|
|
|
493
550
|
*
|
|
494
551
|
* @returns The encrypted inputs.
|
|
495
552
|
*/
|
|
496
|
-
async encrypt(): Promise<
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
await this.requireConnectedOrThrow();
|
|
500
|
-
|
|
501
|
-
const account = await this.getAccountOrThrow();
|
|
502
|
-
const chainId = await this.getChainIdOrThrow();
|
|
553
|
+
async encrypt(): Promise<[...EncryptedItemInputs<T>]> {
|
|
554
|
+
// On hardhat chain, interact with MockZkVerifier contract instead of CoFHE
|
|
555
|
+
if (this.chainId === hardhat.id) return this.mocksEncrypt();
|
|
503
556
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
return await this.mocksEncrypt(account);
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
return await this.productionEncrypt(account, chainId);
|
|
510
|
-
});
|
|
557
|
+
// On other chains, interact with CoFHE coprocessor
|
|
558
|
+
return this.productionEncrypt();
|
|
511
559
|
}
|
|
512
560
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/* eslint-disable no-redeclare */
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import {
|
|
3
|
+
type EncryptableItem,
|
|
4
|
+
isEncryptableItem,
|
|
5
|
+
type EncryptedItemInput,
|
|
6
|
+
type EncryptedItemInputs,
|
|
7
|
+
} from '../types.js';
|
|
5
8
|
|
|
6
9
|
export function encryptExtract<T>(item: T): EncryptableItem[];
|
|
7
10
|
export function encryptExtract<T extends any[]>(item: [...T]): EncryptableItem[];
|
|
@@ -1,11 +1,45 @@
|
|
|
1
|
-
/* eslint-disable no-unused-vars */
|
|
2
|
-
|
|
3
1
|
import { CofhesdkError, CofhesdkErrorCode } from '../error.js';
|
|
4
2
|
import { type EncryptableItem, FheTypes } from '../types.js';
|
|
5
3
|
import { toBigIntOrThrow, validateBigIntInRange, toHexString, hexToBytes } from '../utils.js';
|
|
6
4
|
|
|
7
5
|
// ===== TYPES =====
|
|
8
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Worker function type for ZK proof generation
|
|
9
|
+
* Platform-specific implementations (web) can provide this to enable worker-based proofs
|
|
10
|
+
*/
|
|
11
|
+
export type ZkProveWorkerFunction = (
|
|
12
|
+
fheKeyHex: string,
|
|
13
|
+
crsHex: string,
|
|
14
|
+
items: EncryptableItem[],
|
|
15
|
+
metadata: Uint8Array
|
|
16
|
+
) => Promise<Uint8Array>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Message sent from main thread to worker to request proof generation
|
|
20
|
+
*/
|
|
21
|
+
export interface ZkProveWorkerRequest {
|
|
22
|
+
id: string;
|
|
23
|
+
type: 'zkProve';
|
|
24
|
+
fheKeyHex: string;
|
|
25
|
+
crsHex: string;
|
|
26
|
+
items: Array<{
|
|
27
|
+
utype: string;
|
|
28
|
+
data: any;
|
|
29
|
+
}>;
|
|
30
|
+
metadata: number[]; // Uint8Array serialized as array
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Message sent from worker back to main thread with proof result
|
|
35
|
+
*/
|
|
36
|
+
export interface ZkProveWorkerResponse {
|
|
37
|
+
id: string;
|
|
38
|
+
type: 'success' | 'error' | 'ready';
|
|
39
|
+
result?: number[]; // Uint8Array serialized as array
|
|
40
|
+
error?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
9
43
|
export type VerifyResultRaw = {
|
|
10
44
|
ct_hash: string;
|
|
11
45
|
signature: string;
|
|
@@ -156,15 +190,39 @@ export const zkPack = (items: EncryptableItem[], builder: ZkCiphertextListBuilde
|
|
|
156
190
|
return builder;
|
|
157
191
|
};
|
|
158
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Generates ZK proof using Web Worker (offloads heavy WASM computation)
|
|
195
|
+
* Serializes items and calls the platform-specific worker function
|
|
196
|
+
* @param workerFn - Platform-specific worker function (provided by web/index.ts)
|
|
197
|
+
* @param fheKeyHex - Hex-encoded FHE public key for worker deserialization
|
|
198
|
+
* @param crsHex - Hex-encoded CRS for worker deserialization
|
|
199
|
+
* @param items - Encryptable items to pack in the worker
|
|
200
|
+
* @param metadata - Pre-constructed ZK PoK metadata
|
|
201
|
+
* @returns The serialized proven ciphertext list
|
|
202
|
+
*/
|
|
203
|
+
export const zkProveWithWorker = async (
|
|
204
|
+
workerFn: ZkProveWorkerFunction,
|
|
205
|
+
fheKeyHex: string,
|
|
206
|
+
crsHex: string,
|
|
207
|
+
items: EncryptableItem[],
|
|
208
|
+
metadata: Uint8Array
|
|
209
|
+
): Promise<Uint8Array> => {
|
|
210
|
+
return await workerFn(fheKeyHex, crsHex, items, metadata);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Generates ZK proof using main thread (synchronous WASM)
|
|
215
|
+
* This is the fallback when workers are disabled or unavailable
|
|
216
|
+
* @param builder - The ZK ciphertext list builder with packed inputs
|
|
217
|
+
* @param crs - The Compact PKE CRS for proof generation
|
|
218
|
+
* @param metadata - Pre-constructed ZK PoK metadata
|
|
219
|
+
* @returns The serialized proven ciphertext list
|
|
220
|
+
*/
|
|
159
221
|
export const zkProve = async (
|
|
160
222
|
builder: ZkCiphertextListBuilder,
|
|
161
223
|
crs: ZkCompactPkeCrs,
|
|
162
|
-
|
|
163
|
-
securityZone: number,
|
|
164
|
-
chainId: number
|
|
224
|
+
metadata: Uint8Array
|
|
165
225
|
): Promise<Uint8Array> => {
|
|
166
|
-
const metadata = constructZkPoKMetadata(address, securityZone, chainId);
|
|
167
|
-
|
|
168
226
|
return new Promise((resolve) => {
|
|
169
227
|
setTimeout(() => {
|
|
170
228
|
const compactList = builder.build_with_proof_packed(
|
|
@@ -178,7 +236,11 @@ export const zkProve = async (
|
|
|
178
236
|
});
|
|
179
237
|
};
|
|
180
238
|
|
|
181
|
-
|
|
239
|
+
/**
|
|
240
|
+
* Constructs the ZK Proof of Knowledge metadata for the proof
|
|
241
|
+
* @internal - Used internally within the encrypt module
|
|
242
|
+
*/
|
|
243
|
+
export const constructZkPoKMetadata = (accountAddr: string, securityZone: number, chainId: number): Uint8Array => {
|
|
182
244
|
// Decode the account address from hex
|
|
183
245
|
const accountAddrNoPrefix = accountAddr.startsWith('0x') ? accountAddr.slice(2) : accountAddr;
|
|
184
246
|
const accountBytes = hexToBytes(accountAddrNoPrefix);
|
package/core/error.ts
CHANGED
package/core/fetchKeys.test.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { sepolia, arbSepolia } from '@/chains';
|
|
5
5
|
|
|
6
6
|
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
7
|
-
import { fetchKeys
|
|
7
|
+
import { fetchKeys } from './fetchKeys.js';
|
|
8
8
|
import { type CofhesdkConfig, createCofhesdkConfigBase } from './config.js';
|
|
9
9
|
import { createKeysStore, type KeysStorage } from './keyStore.js';
|
|
10
10
|
|
|
@@ -192,21 +192,4 @@ describe('fetchKeys', () => {
|
|
|
192
192
|
fetchKeys(config, sepolia.id, 0, mockTfhePublicKeyDeserializer, mockCompactPkeCrsDeserializer, keysStorage)
|
|
193
193
|
).rejects.toThrow('Error serializing CRS; Error: Serialization failed');
|
|
194
194
|
});
|
|
195
|
-
|
|
196
|
-
it('should fetch and store FHE public key and CRS for all chains in the config', async () => {
|
|
197
|
-
await fetchMultichainKeys(config, 0, mockTfhePublicKeyDeserializer, mockCompactPkeCrsDeserializer, keysStorage);
|
|
198
|
-
|
|
199
|
-
// Verify keys were stored
|
|
200
|
-
const storedFheKey = keysStorage.getFheKey(sepolia.id, 0);
|
|
201
|
-
const storedCrs = keysStorage.getCrs(sepolia.id);
|
|
202
|
-
const storedFheKeyArb = keysStorage.getFheKey(arbSepolia.id, 0);
|
|
203
|
-
const storedCrsArb = keysStorage.getCrs(arbSepolia.id);
|
|
204
|
-
|
|
205
|
-
expect(storedFheKey).toBeDefined();
|
|
206
|
-
expect(storedCrs).toBeDefined();
|
|
207
|
-
expect(storedFheKeyArb).toBeDefined();
|
|
208
|
-
expect(storedCrsArb).toBeDefined();
|
|
209
|
-
expect(mockTfhePublicKeyDeserializer).toHaveBeenCalled();
|
|
210
|
-
expect(mockCompactPkeCrsDeserializer).toHaveBeenCalled();
|
|
211
|
-
});
|
|
212
195
|
});
|
package/core/fetchKeys.ts
CHANGED
|
@@ -4,7 +4,6 @@ import { type CofhesdkConfig, getCoFheUrlOrThrow } from './config.js';
|
|
|
4
4
|
import { type KeysStorage } from './keyStore.js';
|
|
5
5
|
|
|
6
6
|
const PUBLIC_KEY_LENGTH_MIN = 15_000;
|
|
7
|
-
// eslint-disable-next-line no-unused-vars
|
|
8
7
|
export type FheKeyDeserializer = (buff: string) => void;
|
|
9
8
|
|
|
10
9
|
const checkKeyValidity = (key: string | undefined, serializer: FheKeyDeserializer) => {
|
|
@@ -143,28 +142,3 @@ export const fetchKeys = async (
|
|
|
143
142
|
fetchCrs(coFheUrl, chainId, securityZone, compactPkeCrsDeserializer, keysStorage),
|
|
144
143
|
]);
|
|
145
144
|
};
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Fetches the FHE public key and the CRS for all chains in the config
|
|
149
|
-
* @param {CofhesdkConfig} config - The configuration object for the CoFHE SDK
|
|
150
|
-
* @param {number} securityZone - The security zone for which to retrieve the key (default 0).
|
|
151
|
-
* @param tfhePublicKeyDeserializer - The serializer for the FHE public key (used for validation).
|
|
152
|
-
* @param compactPkeCrsDeserializer - The serializer for the CRS (used for validation).
|
|
153
|
-
* @param keysStorage - The keys storage instance to use (optional)
|
|
154
|
-
* @returns {Promise<void>} - A promise that resolves when the keys are fetched and stored.
|
|
155
|
-
*/
|
|
156
|
-
export const fetchMultichainKeys = async (
|
|
157
|
-
config: CofhesdkConfig,
|
|
158
|
-
securityZone: number = 0,
|
|
159
|
-
tfhePublicKeyDeserializer: FheKeyDeserializer,
|
|
160
|
-
compactPkeCrsDeserializer: FheKeyDeserializer,
|
|
161
|
-
keysStorage?: KeysStorage | null
|
|
162
|
-
): Promise<void> => {
|
|
163
|
-
await Promise.all(
|
|
164
|
-
config.supportedChains
|
|
165
|
-
.filter((chain) => chain.id !== hardhat.id)
|
|
166
|
-
.map((chain) =>
|
|
167
|
-
fetchKeys(config, chain.id, securityZone, tfhePublicKeyDeserializer, compactPkeCrsDeserializer, keysStorage)
|
|
168
|
-
)
|
|
169
|
-
);
|
|
170
|
-
};
|