@cofhe/sdk 0.1.0 → 0.2.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/CHANGELOG.md +62 -0
- package/adapters/ethers5.test.ts +174 -0
- package/adapters/ethers5.ts +36 -0
- package/adapters/ethers6.test.ts +169 -0
- package/adapters/ethers6.ts +36 -0
- package/adapters/hardhat-node.ts +167 -0
- package/adapters/hardhat.hh2.test.ts +159 -0
- package/adapters/hardhat.ts +36 -0
- package/adapters/index.test.ts +20 -0
- package/adapters/index.ts +5 -0
- package/adapters/smartWallet.ts +99 -0
- package/adapters/test-utils.ts +53 -0
- package/adapters/types.ts +6 -0
- package/adapters/wagmi.test.ts +156 -0
- package/adapters/wagmi.ts +17 -0
- package/chains/chains/arbSepolia.ts +14 -0
- package/chains/chains/baseSepolia.ts +14 -0
- package/chains/chains/hardhat.ts +15 -0
- package/chains/chains/localcofhe.ts +14 -0
- package/chains/chains/sepolia.ts +14 -0
- package/chains/chains.test.ts +50 -0
- package/chains/defineChain.ts +18 -0
- package/chains/index.ts +35 -0
- package/chains/types.ts +32 -0
- package/core/baseBuilder.ts +119 -0
- package/core/client.test.ts +315 -0
- package/core/client.ts +292 -0
- package/core/clientTypes.ts +108 -0
- package/core/config.test.ts +235 -0
- package/core/config.ts +220 -0
- package/core/decrypt/MockQueryDecrypterAbi.ts +129 -0
- package/core/decrypt/cofheMocksSealOutput.ts +57 -0
- package/core/decrypt/decryptHandleBuilder.ts +287 -0
- package/core/decrypt/decryptUtils.ts +28 -0
- package/core/decrypt/tnSealOutputV1.ts +59 -0
- package/core/decrypt/tnSealOutputV2.ts +298 -0
- package/core/encrypt/MockZkVerifierAbi.ts +106 -0
- package/core/encrypt/cofheMocksZkVerifySign.ts +284 -0
- package/core/encrypt/encryptInputsBuilder.test.ts +751 -0
- package/core/encrypt/encryptInputsBuilder.ts +560 -0
- package/core/encrypt/encryptUtils.ts +67 -0
- package/core/encrypt/zkPackProveVerify.ts +335 -0
- package/core/error.ts +168 -0
- package/core/fetchKeys.test.ts +195 -0
- package/core/fetchKeys.ts +144 -0
- package/core/index.ts +89 -0
- package/core/keyStore.test.ts +226 -0
- package/core/keyStore.ts +154 -0
- package/core/permits.test.ts +494 -0
- package/core/permits.ts +200 -0
- package/core/types.ts +398 -0
- package/core/utils.ts +130 -0
- package/dist/adapters.cjs +88 -0
- package/dist/adapters.d.cts +14576 -0
- package/dist/adapters.d.ts +14576 -0
- package/dist/adapters.js +83 -0
- package/dist/chains.cjs +114 -0
- package/dist/chains.d.cts +121 -0
- package/dist/chains.d.ts +121 -0
- package/dist/chains.js +1 -0
- package/dist/chunk-UGBVZNRT.js +818 -0
- package/dist/chunk-WEAZ25JO.js +105 -0
- package/dist/chunk-WGCRJCBR.js +2523 -0
- package/dist/clientTypes-5_1nwtUe.d.cts +914 -0
- package/dist/clientTypes-Es7fyi65.d.ts +914 -0
- package/dist/core.cjs +3414 -0
- package/dist/core.d.cts +111 -0
- package/dist/core.d.ts +111 -0
- package/dist/core.js +3 -0
- package/dist/node.cjs +3286 -0
- package/dist/node.d.cts +22 -0
- package/dist/node.d.ts +22 -0
- package/dist/node.js +91 -0
- package/dist/permit-fUSe6KKq.d.cts +349 -0
- package/dist/permit-fUSe6KKq.d.ts +349 -0
- package/dist/permits.cjs +871 -0
- package/dist/permits.d.cts +1045 -0
- package/dist/permits.d.ts +1045 -0
- package/dist/permits.js +1 -0
- package/dist/types-KImPrEIe.d.cts +48 -0
- package/dist/types-KImPrEIe.d.ts +48 -0
- package/dist/web.cjs +3478 -0
- package/dist/web.d.cts +38 -0
- package/dist/web.d.ts +38 -0
- package/dist/web.js +240 -0
- 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 +147 -0
- package/node/config.test.ts +68 -0
- package/node/encryptInputs.test.ts +155 -0
- package/node/index.ts +97 -0
- package/node/storage.ts +51 -0
- package/package.json +27 -15
- package/permits/index.ts +68 -0
- package/permits/localstorage.test.ts +117 -0
- package/permits/permit.test.ts +477 -0
- package/permits/permit.ts +405 -0
- package/permits/sealing.test.ts +84 -0
- package/permits/sealing.ts +131 -0
- package/permits/signature.ts +79 -0
- package/permits/store.test.ts +128 -0
- package/permits/store.ts +166 -0
- package/permits/test-utils.ts +20 -0
- package/permits/types.ts +191 -0
- package/permits/utils.ts +62 -0
- package/permits/validation.test.ts +288 -0
- package/permits/validation.ts +369 -0
- package/web/client.web.test.ts +147 -0
- package/web/config.web.test.ts +69 -0
- package/web/encryptInputs.web.test.ts +172 -0
- package/web/index.ts +161 -0
- package/web/storage.ts +34 -0
- 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
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { type EncryptableItem, FheTypes } from '../types.js';
|
|
2
|
+
import { MAX_ENCRYPTABLE_BITS, type VerifyResult } from './zkPackProveVerify.js';
|
|
3
|
+
import {
|
|
4
|
+
createWalletClient,
|
|
5
|
+
http,
|
|
6
|
+
encodePacked,
|
|
7
|
+
keccak256,
|
|
8
|
+
hashMessage,
|
|
9
|
+
toBytes,
|
|
10
|
+
type PublicClient,
|
|
11
|
+
type WalletClient,
|
|
12
|
+
} from 'viem';
|
|
13
|
+
import { MockZkVerifierAbi } from './MockZkVerifierAbi.js';
|
|
14
|
+
import { hardhat } from 'viem/chains';
|
|
15
|
+
import { CofhesdkError, CofhesdkErrorCode } from '../error.js';
|
|
16
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
17
|
+
|
|
18
|
+
// Address the Mock ZkVerifier contract is deployed to on the Hardhat chain
|
|
19
|
+
export const MocksZkVerifierAddress = '0x0000000000000000000000000000000000000100';
|
|
20
|
+
|
|
21
|
+
// PK & address pair for zk verifier
|
|
22
|
+
export const MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY =
|
|
23
|
+
'0x6C8D7F768A6BB4AAFE85E8A2F5A9680355239C7E14646ED62B044E39DE154512';
|
|
24
|
+
export const MOCKS_ZK_VERIFIER_SIGNER_ADDRESS = '0x6E12D8C87503D4287c294f2Fdef96ACd9DFf6bd2';
|
|
25
|
+
|
|
26
|
+
type EncryptableItemWithCtHash = EncryptableItem & {
|
|
27
|
+
ctHash: bigint;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function createMockZkVerifierSigner() {
|
|
31
|
+
return createWalletClient({
|
|
32
|
+
chain: hardhat,
|
|
33
|
+
transport: http(),
|
|
34
|
+
account: privateKeyToAccount(MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The mocks don't use a tfhe builder, so we check the encryptable bits here to preserve parity
|
|
39
|
+
*/
|
|
40
|
+
export async function cofheMocksCheckEncryptableBits(items: EncryptableItem[]): Promise<void> {
|
|
41
|
+
let totalBits = 0;
|
|
42
|
+
for (const item of items) {
|
|
43
|
+
switch (item.utype) {
|
|
44
|
+
case FheTypes.Bool: {
|
|
45
|
+
totalBits += 1;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
case FheTypes.Uint8: {
|
|
49
|
+
totalBits += 8;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case FheTypes.Uint16: {
|
|
53
|
+
totalBits += 16;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case FheTypes.Uint32: {
|
|
57
|
+
totalBits += 32;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
case FheTypes.Uint64: {
|
|
61
|
+
totalBits += 64;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
case FheTypes.Uint128: {
|
|
65
|
+
totalBits += 128;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
// [U256-DISABLED]
|
|
69
|
+
// case FheTypes.Uint256: {
|
|
70
|
+
// totalBits += 256;
|
|
71
|
+
// break;
|
|
72
|
+
// }
|
|
73
|
+
case FheTypes.Uint160: {
|
|
74
|
+
totalBits += 160;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (totalBits > MAX_ENCRYPTABLE_BITS) {
|
|
80
|
+
throw new CofhesdkError({
|
|
81
|
+
code: CofhesdkErrorCode.ZkPackFailed,
|
|
82
|
+
message: `Total bits ${totalBits} exceeds ${MAX_ENCRYPTABLE_BITS}`,
|
|
83
|
+
hint: `Ensure that the total bits of the items to encrypt does not exceed ${MAX_ENCRYPTABLE_BITS}`,
|
|
84
|
+
context: {
|
|
85
|
+
totalBits,
|
|
86
|
+
maxBits: MAX_ENCRYPTABLE_BITS,
|
|
87
|
+
items,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* In the mocks context, we use the MockZkVerifier contract to calculate the ctHashes.
|
|
95
|
+
*/
|
|
96
|
+
async function calcCtHashes(
|
|
97
|
+
items: EncryptableItem[],
|
|
98
|
+
account: string,
|
|
99
|
+
securityZone: number,
|
|
100
|
+
publicClient: PublicClient
|
|
101
|
+
): Promise<EncryptableItemWithCtHash[]> {
|
|
102
|
+
const calcCtHashesArgs = [
|
|
103
|
+
items.map(({ data }) => BigInt(data)),
|
|
104
|
+
items.map(({ utype }) => utype),
|
|
105
|
+
account as `0x${string}`,
|
|
106
|
+
securityZone,
|
|
107
|
+
BigInt(hardhat.id),
|
|
108
|
+
] as const;
|
|
109
|
+
|
|
110
|
+
let ctHashes: bigint[];
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
ctHashes = (await publicClient.readContract({
|
|
114
|
+
address: MocksZkVerifierAddress,
|
|
115
|
+
abi: MockZkVerifierAbi,
|
|
116
|
+
functionName: 'zkVerifyCalcCtHashesPacked',
|
|
117
|
+
args: calcCtHashesArgs,
|
|
118
|
+
})) as bigint[];
|
|
119
|
+
} catch (err) {
|
|
120
|
+
throw new CofhesdkError({
|
|
121
|
+
code: CofhesdkErrorCode.ZkMocksCalcCtHashesFailed,
|
|
122
|
+
message: `mockZkVerifySign calcCtHashes failed while calling zkVerifyCalcCtHashesPacked`,
|
|
123
|
+
cause: err instanceof Error ? err : undefined,
|
|
124
|
+
context: {
|
|
125
|
+
address: MocksZkVerifierAddress,
|
|
126
|
+
items,
|
|
127
|
+
account,
|
|
128
|
+
securityZone,
|
|
129
|
+
publicClient,
|
|
130
|
+
calcCtHashesArgs,
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (ctHashes.length !== items.length) {
|
|
136
|
+
throw new CofhesdkError({
|
|
137
|
+
code: CofhesdkErrorCode.ZkMocksCalcCtHashesFailed,
|
|
138
|
+
message: `mockZkVerifySign calcCtHashes returned incorrect number of ctHashes`,
|
|
139
|
+
context: {
|
|
140
|
+
items,
|
|
141
|
+
account,
|
|
142
|
+
securityZone,
|
|
143
|
+
publicClient,
|
|
144
|
+
calcCtHashesArgs,
|
|
145
|
+
ctHashes,
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return items.map((item, index) => ({
|
|
151
|
+
...item,
|
|
152
|
+
ctHash: ctHashes[index],
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Insert the calculated ctHashes into the MockZkVerifier contract along with the plaintext values.
|
|
158
|
+
* The plaintext values are used on chain to simulate the true FHE operations.
|
|
159
|
+
*/
|
|
160
|
+
async function insertCtHashes(items: EncryptableItemWithCtHash[], walletClient: WalletClient): Promise<void> {
|
|
161
|
+
const insertPackedCtHashesArgs = [items.map(({ ctHash }) => ctHash), items.map(({ data }) => BigInt(data))] as const;
|
|
162
|
+
try {
|
|
163
|
+
const account = walletClient.account!;
|
|
164
|
+
|
|
165
|
+
await walletClient.writeContract({
|
|
166
|
+
address: MocksZkVerifierAddress,
|
|
167
|
+
abi: MockZkVerifierAbi,
|
|
168
|
+
functionName: 'insertPackedCtHashes',
|
|
169
|
+
args: insertPackedCtHashesArgs,
|
|
170
|
+
chain: hardhat,
|
|
171
|
+
account: account,
|
|
172
|
+
});
|
|
173
|
+
} catch (err) {
|
|
174
|
+
throw new CofhesdkError({
|
|
175
|
+
code: CofhesdkErrorCode.ZkMocksInsertCtHashesFailed,
|
|
176
|
+
message: `mockZkVerifySign insertPackedCtHashes failed while calling insertPackedCtHashes`,
|
|
177
|
+
cause: err instanceof Error ? err : undefined,
|
|
178
|
+
context: {
|
|
179
|
+
items,
|
|
180
|
+
walletClient,
|
|
181
|
+
insertPackedCtHashesArgs,
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The mocks verify the EncryptedInputs' signature against the known proof signer account.
|
|
189
|
+
* Locally, we create the proof signatures from the known proof signer account.
|
|
190
|
+
*/
|
|
191
|
+
async function createProofSignatures(items: EncryptableItemWithCtHash[], securityZone: number): Promise<string[]> {
|
|
192
|
+
let signatures: string[] = [];
|
|
193
|
+
|
|
194
|
+
// Create wallet client for the encrypted input signer
|
|
195
|
+
// This wallet won't send a transaction, so gas isn't needed
|
|
196
|
+
// This wallet doesn't need to be connected to the network
|
|
197
|
+
let encInputSignerClient: WalletClient | undefined;
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
encInputSignerClient = createMockZkVerifierSigner();
|
|
201
|
+
} catch (err) {
|
|
202
|
+
throw new CofhesdkError({
|
|
203
|
+
code: CofhesdkErrorCode.ZkMocksCreateProofSignatureFailed,
|
|
204
|
+
message: `mockZkVerifySign createProofSignatures failed while creating wallet client`,
|
|
205
|
+
cause: err instanceof Error ? err : undefined,
|
|
206
|
+
context: {
|
|
207
|
+
MOCKS_ZK_VERIFIER_SIGNER_PRIVATE_KEY,
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
try {
|
|
213
|
+
for (const item of items) {
|
|
214
|
+
// Pack the data into bytes and hash it
|
|
215
|
+
const packedData = encodePacked(['uint256', 'int32', 'uint8'], [BigInt(item.data), securityZone, item.utype]);
|
|
216
|
+
const messageHash = keccak256(packedData);
|
|
217
|
+
|
|
218
|
+
// Convert to EthSignedMessageHash (adds "\x19Ethereum Signed Message:\n32" prefix)
|
|
219
|
+
const ethSignedHash = hashMessage({ raw: toBytes(messageHash) });
|
|
220
|
+
|
|
221
|
+
// Sign the message
|
|
222
|
+
const signature = await encInputSignerClient.signMessage({
|
|
223
|
+
message: { raw: toBytes(ethSignedHash) },
|
|
224
|
+
account: encInputSignerClient.account!,
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
signatures.push(signature);
|
|
228
|
+
}
|
|
229
|
+
} catch (err) {
|
|
230
|
+
throw new CofhesdkError({
|
|
231
|
+
code: CofhesdkErrorCode.ZkMocksCreateProofSignatureFailed,
|
|
232
|
+
message: `mockZkVerifySign createProofSignatures failed while calling signMessage`,
|
|
233
|
+
cause: err instanceof Error ? err : undefined,
|
|
234
|
+
context: {
|
|
235
|
+
items,
|
|
236
|
+
securityZone,
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (signatures.length !== items.length) {
|
|
242
|
+
throw new CofhesdkError({
|
|
243
|
+
code: CofhesdkErrorCode.ZkMocksCreateProofSignatureFailed,
|
|
244
|
+
message: `mockZkVerifySign createProofSignatures returned incorrect number of signatures`,
|
|
245
|
+
context: {
|
|
246
|
+
items,
|
|
247
|
+
securityZone,
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return signatures;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Transforms the encryptable items into EncryptedInputs ready to be used in a transaction on the hardhat chain.
|
|
257
|
+
* The EncryptedInputs are returned in the same format as from CoFHE, and include on-chain verifiable signatures.
|
|
258
|
+
*/
|
|
259
|
+
export async function cofheMocksZkVerifySign(
|
|
260
|
+
items: EncryptableItem[],
|
|
261
|
+
account: string,
|
|
262
|
+
securityZone: number,
|
|
263
|
+
publicClient: PublicClient,
|
|
264
|
+
walletClient: WalletClient,
|
|
265
|
+
zkvWalletClient: WalletClient | undefined
|
|
266
|
+
): Promise<VerifyResult[]> {
|
|
267
|
+
// Use config._internal?.zkvWalletClient if provided, otherwise use a mock zk verifier signer
|
|
268
|
+
const _walletClient = zkvWalletClient ?? createMockZkVerifierSigner();
|
|
269
|
+
|
|
270
|
+
// Call MockZkVerifier contract to calculate the ctHashes
|
|
271
|
+
const encryptableItems = await calcCtHashes(items, account, securityZone, publicClient);
|
|
272
|
+
|
|
273
|
+
// Insert the ctHashes into the MockZkVerifier contract
|
|
274
|
+
await insertCtHashes(encryptableItems, _walletClient);
|
|
275
|
+
|
|
276
|
+
// Locally create the proof signatures from the known proof signer account
|
|
277
|
+
const signatures = await createProofSignatures(encryptableItems, securityZone);
|
|
278
|
+
|
|
279
|
+
// Return the ctHashes and signatures in the same format as CoFHE
|
|
280
|
+
return encryptableItems.map((item, index) => ({
|
|
281
|
+
ct_hash: item.ctHash.toString(),
|
|
282
|
+
signature: signatures[index],
|
|
283
|
+
}));
|
|
284
|
+
}
|