@baerae/zkap-zkp-react-native 0.1.4 → 0.1.6
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 +24 -1
- package/ZkapReactNative.podspec +42 -0
- package/android/CMakeLists.txt +81 -0
- package/android/build.gradle +111 -14
- package/android/cpp-adapter.cpp +43 -0
- package/android/libs/arm64-v8a/libzkap_uniffi_bindings.so +0 -0
- package/android/libs/x86_64/libzkap_uniffi_bindings.so +0 -0
- package/android/proguard-rules.pro +2 -0
- package/android/src/main/AndroidManifest.xml +5 -0
- package/android/src/main/java/com/baerae/zkapreactnative/ZkapReactNativeModule.kt +51 -0
- package/android/src/main/java/com/baerae/zkapreactnative/ZkapReactNativePackage.kt +34 -0
- package/cpp/baerae-zkap-react-native.cpp +17 -0
- package/cpp/baerae-zkap-react-native.h +15 -0
- package/cpp/generated/zkap_uniffi_bindings.cpp +2154 -0
- package/cpp/generated/zkap_uniffi_bindings.hpp +66 -0
- package/ios/ZkapReactNative.h +16 -0
- package/ios/ZkapReactNative.mm +412 -0
- package/ios/ZkapZkp.xcframework/Info.plist +5 -5
- package/ios/ZkapZkp.xcframework/ios-arm64/libzkap_uniffi_bindings.a +0 -0
- package/ios/ZkapZkp.xcframework/ios-arm64_x86_64-simulator/libzkap_uniffi_bindings.a +0 -0
- package/package.json +37 -14
- package/src/NativeZkapReactNative.ts +11 -0
- package/src/generated/zkap_uniffi_bindings-ffi.ts +150 -0
- package/src/generated/zkap_uniffi_bindings.ts +1015 -0
- package/src/index.ts +250 -46
- package/ubrn.config.yaml +13 -0
- package/android/libs/armeabi-v7a/libzkap_uniffi_bindings.so +0 -0
- package/android/src/main/java/expo/modules/zkap/ZkapSdkModule.kt +0 -153
- package/android/src/main/java/uniffi/zkap_uniffi_bindings/zkap_uniffi_bindings.kt +0 -1566
- package/expo-module.config.json +0 -9
- package/ios/ZkapSdkModule.podspec +0 -35
- package/ios/ZkapSdkModule.swift +0 -147
- package/ios/uniffi/zkap_uniffi_bindings.swift +0 -1174
- package/ios/uniffi/zkap_uniffi_bindingsFFI.h +0 -567
- package/ios/uniffi/zkap_uniffi_bindingsFFI.modulemap +0 -7
package/src/index.ts
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import NativeZkapReactNative from './NativeZkapReactNative';
|
|
2
|
+
import { Platform } from 'react-native';
|
|
3
|
+
import generatedBindings, {
|
|
4
|
+
generateAnchor as nativeGenerateAnchor,
|
|
5
|
+
generateAudHash as nativeGenerateAudHash,
|
|
6
|
+
generateHash as nativeGenerateHash,
|
|
7
|
+
generateLeafHash as nativeGenerateLeafHash,
|
|
8
|
+
prepareWitnessInputs as nativePrepareWitnessInputs,
|
|
9
|
+
prove as nativeProve,
|
|
10
|
+
proveFromWitnessBundleFile as nativeProveFromWitnessBundleFile,
|
|
11
|
+
type ZkapCircuitConfig,
|
|
12
|
+
type ZkapPreparedWitnessInputs,
|
|
13
|
+
type ZkapProofRequest,
|
|
14
|
+
type ZkapProveCredential,
|
|
15
|
+
type ZkapWitnessBundleFile,
|
|
16
|
+
} from './generated/zkap_uniffi_bindings';
|
|
4
17
|
|
|
5
18
|
// ──────────────────────────────────────────────────────────────────
|
|
6
19
|
// Input / Output types
|
|
@@ -28,34 +41,212 @@ export interface Secret {
|
|
|
28
41
|
aud: string;
|
|
29
42
|
}
|
|
30
43
|
|
|
44
|
+
export interface ProveCredential {
|
|
45
|
+
jwt: string;
|
|
46
|
+
rsa_modulus_b64?: string;
|
|
47
|
+
rsaModulusB64?: string;
|
|
48
|
+
merkle_path?: string[];
|
|
49
|
+
merklePath?: string[];
|
|
50
|
+
merkle_leaf_idx?: number;
|
|
51
|
+
merkleLeafIdx?: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
31
54
|
export interface ProveRequest {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
pk_ops: string[];
|
|
35
|
-
merkle_paths: string[][];
|
|
36
|
-
leaf_indices: number[];
|
|
37
|
-
root: string;
|
|
38
|
-
/** Anchor polynomial evaluations (N - K + 1 entries). */
|
|
39
|
-
anchor_evals: string[];
|
|
40
|
-
/** Anchor chain hash (hanchor). */
|
|
41
|
-
hanchor: string;
|
|
42
|
-
h_sign_user_op: string;
|
|
55
|
+
manifest_dir?: string;
|
|
56
|
+
manifestDir?: string;
|
|
43
57
|
random: string;
|
|
44
|
-
|
|
45
|
-
|
|
58
|
+
h_sign_user_op?: string;
|
|
59
|
+
hSignUserOp?: string;
|
|
60
|
+
anchor: string[];
|
|
61
|
+
merkle_root?: string;
|
|
62
|
+
merkleRoot?: string;
|
|
63
|
+
credentials: ProveCredential[];
|
|
46
64
|
}
|
|
47
65
|
|
|
48
66
|
export interface ProveResult {
|
|
49
67
|
/** Solidity-compatible proof per proof: [ax, ay, bx_c1, bx_c0, by_c1, by_c0, cx, cy] */
|
|
50
68
|
proofs: string[][];
|
|
51
|
-
/** Public inputs shared across all JWTs
|
|
69
|
+
/** Public inputs shared across all JWTs as decimal strings. */
|
|
52
70
|
shared_inputs: string[];
|
|
53
|
-
/** partial_rhs per JWT
|
|
71
|
+
/** partial_rhs per JWT as decimal string. */
|
|
54
72
|
partial_rhs_list: string[];
|
|
55
|
-
/** jwt_exp per JWT
|
|
73
|
+
/** jwt_exp per JWT as decimal string. */
|
|
56
74
|
jwt_exp_list: string[];
|
|
57
75
|
}
|
|
58
76
|
|
|
77
|
+
let initialized = false;
|
|
78
|
+
const IOS_WITNESS_CHUNK_SIZE = 4 * 1024 * 1024;
|
|
79
|
+
|
|
80
|
+
function ensureInitialized(): void {
|
|
81
|
+
if (initialized) return;
|
|
82
|
+
NativeZkapReactNative.installRustCrate();
|
|
83
|
+
generatedBindings.initialize();
|
|
84
|
+
initialized = true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
type ZkapUniFfiError = Error & {
|
|
88
|
+
tag?: string;
|
|
89
|
+
inner?: {
|
|
90
|
+
message?: string;
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
function withZkapErrorMessage<T>(fn: () => T): T {
|
|
95
|
+
try {
|
|
96
|
+
return fn();
|
|
97
|
+
} catch (error) {
|
|
98
|
+
const zkapError = error as ZkapUniFfiError;
|
|
99
|
+
const message = zkapError?.inner?.message;
|
|
100
|
+
if (typeof message === 'string' && message.length > 0) {
|
|
101
|
+
const wrapped = new Error(message);
|
|
102
|
+
wrapped.name = zkapError.tag
|
|
103
|
+
? `ZkapError.${zkapError.tag}`
|
|
104
|
+
: zkapError.name || 'ZkapError';
|
|
105
|
+
(wrapped as Error & { cause?: unknown }).cause = error;
|
|
106
|
+
throw wrapped;
|
|
107
|
+
}
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function toNativeConfig(config: CircuitConfig): ZkapCircuitConfig {
|
|
113
|
+
return {
|
|
114
|
+
maxJwtB64Len: BigInt(config.max_jwt_b64_len),
|
|
115
|
+
maxPayloadB64Len: BigInt(config.max_payload_b64_len),
|
|
116
|
+
maxAudLen: BigInt(config.max_aud_len),
|
|
117
|
+
maxExpLen: BigInt(config.max_exp_len),
|
|
118
|
+
maxIssLen: BigInt(config.max_iss_len),
|
|
119
|
+
maxNonceLen: BigInt(config.max_nonce_len),
|
|
120
|
+
maxSubLen: BigInt(config.max_sub_len),
|
|
121
|
+
n: BigInt(config.n),
|
|
122
|
+
k: BigInt(config.k),
|
|
123
|
+
treeHeight: BigInt(config.tree_height),
|
|
124
|
+
numAudienceLimit: BigInt(config.num_audience_limit),
|
|
125
|
+
claims: config.claims,
|
|
126
|
+
forbiddenString: config.forbidden_string,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function requireString(value: string | undefined, field: string): string {
|
|
131
|
+
if (!value) {
|
|
132
|
+
throw new Error(`[zkap/sdk-react-native] missing ${field}`);
|
|
133
|
+
}
|
|
134
|
+
return value;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function requireArray<T>(value: T[] | undefined, field: string): T[] {
|
|
138
|
+
if (!value) {
|
|
139
|
+
throw new Error(`[zkap/sdk-react-native] missing ${field}`);
|
|
140
|
+
}
|
|
141
|
+
return value;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function requireNumber(value: number | undefined, field: string): number {
|
|
145
|
+
if (value === undefined || value === null) {
|
|
146
|
+
throw new Error(`[zkap/sdk-react-native] missing ${field}`);
|
|
147
|
+
}
|
|
148
|
+
return value;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function toNativeCredential(credential: ProveCredential): ZkapProveCredential {
|
|
152
|
+
return {
|
|
153
|
+
jwt: credential.jwt,
|
|
154
|
+
rsaModulusB64: requireString(
|
|
155
|
+
credential.rsa_modulus_b64 ?? credential.rsaModulusB64,
|
|
156
|
+
'credential.rsa_modulus_b64',
|
|
157
|
+
),
|
|
158
|
+
merklePath: requireArray(
|
|
159
|
+
credential.merkle_path ?? credential.merklePath,
|
|
160
|
+
'credential.merkle_path',
|
|
161
|
+
),
|
|
162
|
+
merkleLeafIdx: BigInt(
|
|
163
|
+
requireNumber(
|
|
164
|
+
credential.merkle_leaf_idx ?? credential.merkleLeafIdx,
|
|
165
|
+
'credential.merkle_leaf_idx',
|
|
166
|
+
),
|
|
167
|
+
),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function toNativeRequest(request: ProveRequest): ZkapProofRequest {
|
|
172
|
+
return {
|
|
173
|
+
manifestDir: requireString(
|
|
174
|
+
request.manifest_dir ?? request.manifestDir,
|
|
175
|
+
'manifest_dir',
|
|
176
|
+
),
|
|
177
|
+
random: request.random,
|
|
178
|
+
hSignUserOp: requireString(
|
|
179
|
+
request.h_sign_user_op ?? request.hSignUserOp,
|
|
180
|
+
'h_sign_user_op',
|
|
181
|
+
),
|
|
182
|
+
anchor: request.anchor,
|
|
183
|
+
merkleRoot: requireString(
|
|
184
|
+
request.merkle_root ?? request.merkleRoot,
|
|
185
|
+
'merkle_root',
|
|
186
|
+
),
|
|
187
|
+
credentials: request.credentials.map(toNativeCredential),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function toProofResult(result: {
|
|
192
|
+
proofs: string[][];
|
|
193
|
+
sharedInputs: string[];
|
|
194
|
+
partialRhsList: string[];
|
|
195
|
+
jwtExpList: string[];
|
|
196
|
+
}): ProveResult {
|
|
197
|
+
return {
|
|
198
|
+
proofs: result.proofs,
|
|
199
|
+
shared_inputs: result.sharedInputs,
|
|
200
|
+
partial_rhs_list: result.partialRhsList,
|
|
201
|
+
jwt_exp_list: result.jwtExpList,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function makeRunId(): string {
|
|
206
|
+
return `zkap-${Date.now().toString(36)}-${Math.random()
|
|
207
|
+
.toString(36)
|
|
208
|
+
.slice(2)}`;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
type IosWitnessRunnerResult = {
|
|
212
|
+
witnessBundlePath?: unknown;
|
|
213
|
+
sha256?: unknown;
|
|
214
|
+
byteLength?: unknown;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
async function runIosWitness(
|
|
218
|
+
prepared: ZkapPreparedWitnessInputs,
|
|
219
|
+
): Promise<ZkapWitnessBundleFile> {
|
|
220
|
+
const inputJson = JSON.stringify({
|
|
221
|
+
run_id: makeRunId(),
|
|
222
|
+
chunk_size: IOS_WITNESS_CHUNK_SIZE,
|
|
223
|
+
wasm_base64: prepared.wasmBase64,
|
|
224
|
+
request_json_base64: prepared.requestJsonBase64,
|
|
225
|
+
config_json_base64: prepared.configJsonBase64,
|
|
226
|
+
witness_gen_sha256: prepared.witnessGenSha256,
|
|
227
|
+
request_json_sha256: prepared.requestJsonSha256,
|
|
228
|
+
config_json_sha256: prepared.configJsonSha256,
|
|
229
|
+
wasm_byte_length: prepared.wasmByteLength.toString(),
|
|
230
|
+
request_json_byte_length: prepared.requestJsonByteLength.toString(),
|
|
231
|
+
config_json_byte_length: prepared.configJsonByteLength.toString(),
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
const resultJson = await NativeZkapReactNative.runWitnessInWkWebView(inputJson);
|
|
235
|
+
const parsed = JSON.parse(resultJson) as IosWitnessRunnerResult;
|
|
236
|
+
if (
|
|
237
|
+
typeof parsed.witnessBundlePath !== 'string' ||
|
|
238
|
+
typeof parsed.sha256 !== 'string' ||
|
|
239
|
+
typeof parsed.byteLength !== 'number'
|
|
240
|
+
) {
|
|
241
|
+
throw new Error('[zkap/sdk-react-native] invalid WKWebView witness result');
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
witnessBundlePath: parsed.witnessBundlePath,
|
|
245
|
+
sha256: parsed.sha256,
|
|
246
|
+
byteLength: BigInt(parsed.byteLength),
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
59
250
|
// ──────────────────────────────────────────────────────────────────
|
|
60
251
|
// Supported API
|
|
61
252
|
// ──────────────────────────────────────────────────────────────────
|
|
@@ -65,10 +256,8 @@ export interface ProveResult {
|
|
|
65
256
|
* Returns the result as a 0x-prefixed hex string.
|
|
66
257
|
*/
|
|
67
258
|
export async function generateHash(messages: string[]): Promise<string> {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
);
|
|
71
|
-
return JSON.parse(result).result as string;
|
|
259
|
+
ensureInitialized();
|
|
260
|
+
return withZkapErrorMessage(() => nativeGenerateHash(messages));
|
|
72
261
|
}
|
|
73
262
|
|
|
74
263
|
/**
|
|
@@ -77,12 +266,10 @@ export async function generateHash(messages: string[]): Promise<string> {
|
|
|
77
266
|
*/
|
|
78
267
|
export async function generateAnchor(
|
|
79
268
|
config: CircuitConfig,
|
|
80
|
-
secrets: Secret[]
|
|
269
|
+
secrets: Secret[],
|
|
81
270
|
): Promise<{ evaluations: string[] }> {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
);
|
|
85
|
-
return JSON.parse(result) as { evaluations: string[] };
|
|
271
|
+
ensureInitialized();
|
|
272
|
+
return withZkapErrorMessage(() => nativeGenerateAnchor(toNativeConfig(config), secrets));
|
|
86
273
|
}
|
|
87
274
|
|
|
88
275
|
/**
|
|
@@ -90,12 +277,16 @@ export async function generateAnchor(
|
|
|
90
277
|
*/
|
|
91
278
|
export async function generateAudHash(
|
|
92
279
|
config: CircuitConfig,
|
|
93
|
-
aud_list: string[]
|
|
280
|
+
aud_list: string[],
|
|
94
281
|
): Promise<{ aud_hashes: string[]; h_aud_list: string }> {
|
|
95
|
-
|
|
96
|
-
|
|
282
|
+
ensureInitialized();
|
|
283
|
+
const result = withZkapErrorMessage(() =>
|
|
284
|
+
nativeGenerateAudHash(toNativeConfig(config), aud_list)
|
|
97
285
|
);
|
|
98
|
-
return
|
|
286
|
+
return {
|
|
287
|
+
aud_hashes: result.audHashes,
|
|
288
|
+
h_aud_list: result.hAudList,
|
|
289
|
+
};
|
|
99
290
|
}
|
|
100
291
|
|
|
101
292
|
/**
|
|
@@ -104,26 +295,40 @@ export async function generateAudHash(
|
|
|
104
295
|
export async function generateLeafHash(
|
|
105
296
|
config: CircuitConfig,
|
|
106
297
|
iss: string,
|
|
107
|
-
pk_b64: string
|
|
298
|
+
pk_b64: string,
|
|
108
299
|
): Promise<string> {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
);
|
|
112
|
-
return JSON.parse(result).result as string;
|
|
300
|
+
ensureInitialized();
|
|
301
|
+
return withZkapErrorMessage(() => nativeGenerateLeafHash(toNativeConfig(config), iss, pk_b64));
|
|
113
302
|
}
|
|
114
303
|
|
|
115
304
|
/**
|
|
116
305
|
* Generate Groth16 proofs (on-device proving).
|
|
117
|
-
*
|
|
306
|
+
*
|
|
307
|
+
* Requires a manifest-validated CRS directory containing manifest.json,
|
|
308
|
+
* circuit.ar1cs, pk.bin, vk.bin, pvk.bin, config.json, and witness_gen.wasm.
|
|
118
309
|
*/
|
|
119
310
|
export async function prove(
|
|
120
311
|
config: CircuitConfig,
|
|
121
|
-
request: ProveRequest
|
|
312
|
+
request: ProveRequest,
|
|
122
313
|
): Promise<ProveResult> {
|
|
123
|
-
|
|
124
|
-
|
|
314
|
+
ensureInitialized();
|
|
315
|
+
const nativeConfig = toNativeConfig(config);
|
|
316
|
+
const nativeRequest = toNativeRequest(request);
|
|
317
|
+
if (Platform.OS === 'ios') {
|
|
318
|
+
const prepared = withZkapErrorMessage(() =>
|
|
319
|
+
nativePrepareWitnessInputs(nativeConfig, nativeRequest)
|
|
320
|
+
);
|
|
321
|
+
const witness = await runIosWitness(prepared);
|
|
322
|
+
return toProofResult(
|
|
323
|
+
withZkapErrorMessage(() =>
|
|
324
|
+
nativeProveFromWitnessBundleFile(nativeConfig, nativeRequest, witness)
|
|
325
|
+
)
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return toProofResult(
|
|
330
|
+
withZkapErrorMessage(() => nativeProve(nativeConfig, nativeRequest))
|
|
125
331
|
);
|
|
126
|
-
return JSON.parse(result) as ProveResult;
|
|
127
332
|
}
|
|
128
333
|
|
|
129
334
|
// ──────────────────────────────────────────────────────────────────
|
|
@@ -137,18 +342,17 @@ export async function prove(
|
|
|
137
342
|
export function groth16Setup(): never {
|
|
138
343
|
throw new Error(
|
|
139
344
|
'[zkap/sdk-react-native] groth16Setup() is not supported on mobile. ' +
|
|
140
|
-
'Note: this function has been removed from all SDK packages as of v0.1.2.'
|
|
345
|
+
'Note: this function has been removed from all SDK packages as of v0.1.2.',
|
|
141
346
|
);
|
|
142
347
|
}
|
|
143
348
|
|
|
144
349
|
/**
|
|
145
350
|
* NOT supported on React Native.
|
|
146
|
-
*
|
|
351
|
+
* Verification is currently kept on-chain / server-side for mobile consumers.
|
|
147
352
|
*/
|
|
148
353
|
export function verify(): never {
|
|
149
354
|
throw new Error(
|
|
150
355
|
'[zkap/sdk-react-native] verify() is not supported on mobile. ' +
|
|
151
|
-
'
|
|
356
|
+
'Use the on-chain verifier or the Node SDK verify() helper.',
|
|
152
357
|
);
|
|
153
358
|
}
|
|
154
|
-
|
package/ubrn.config.yaml
ADDED
|
Binary file
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
package expo.modules.zkap
|
|
2
|
-
|
|
3
|
-
import expo.modules.kotlin.modules.Module
|
|
4
|
-
import expo.modules.kotlin.modules.ModuleDefinition
|
|
5
|
-
import org.json.JSONArray
|
|
6
|
-
import org.json.JSONObject
|
|
7
|
-
import uniffi.zkap_uniffi_bindings.*
|
|
8
|
-
|
|
9
|
-
@OptIn(kotlin.ExperimentalUnsignedTypes::class)
|
|
10
|
-
class ZkapSdkModule : Module() {
|
|
11
|
-
|
|
12
|
-
override fun definition() = ModuleDefinition {
|
|
13
|
-
Name("ZkapSdk")
|
|
14
|
-
|
|
15
|
-
AsyncFunction("generateHash") { inputJson: String ->
|
|
16
|
-
try {
|
|
17
|
-
val obj = JSONObject(inputJson)
|
|
18
|
-
val messagesArr = obj.getJSONArray("messages")
|
|
19
|
-
val messages = List(messagesArr.length()) { messagesArr.getString(it) }
|
|
20
|
-
val result = generateHash(messages)
|
|
21
|
-
JSONObject().put("result", result).toString()
|
|
22
|
-
} catch (e: ZkapException) {
|
|
23
|
-
throw ZkapError(e.message ?: "ZkapException")
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
AsyncFunction("generateAudHash") { inputJson: String ->
|
|
28
|
-
try {
|
|
29
|
-
val obj = JSONObject(inputJson)
|
|
30
|
-
val config = parseConfig(obj.getJSONObject("config"))
|
|
31
|
-
val audArr = obj.getJSONArray("aud_list")
|
|
32
|
-
val audList = List(audArr.length()) { audArr.getString(it) }
|
|
33
|
-
val result = generateAudHash(config, audList)
|
|
34
|
-
val audHashesArr = JSONArray(result.audHashes)
|
|
35
|
-
JSONObject()
|
|
36
|
-
.put("aud_hashes", audHashesArr)
|
|
37
|
-
.put("h_aud_list", result.hAudList)
|
|
38
|
-
.toString()
|
|
39
|
-
} catch (e: ZkapException) {
|
|
40
|
-
throw ZkapError(e.message ?: "ZkapException")
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
AsyncFunction("generateLeafHash") { inputJson: String ->
|
|
45
|
-
try {
|
|
46
|
-
val obj = JSONObject(inputJson)
|
|
47
|
-
val config = parseConfig(obj.getJSONObject("config"))
|
|
48
|
-
val iss = obj.getString("iss")
|
|
49
|
-
val pkB64 = obj.getString("pk_b64")
|
|
50
|
-
val result = generateLeafHash(config, iss, pkB64)
|
|
51
|
-
JSONObject().put("result", result).toString()
|
|
52
|
-
} catch (e: ZkapException) {
|
|
53
|
-
throw ZkapError(e.message ?: "ZkapException")
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
AsyncFunction("generateAnchor") { inputJson: String ->
|
|
58
|
-
try {
|
|
59
|
-
val obj = JSONObject(inputJson)
|
|
60
|
-
val config = parseConfig(obj.getJSONObject("config"))
|
|
61
|
-
val secretsArr = obj.getJSONArray("secrets")
|
|
62
|
-
val secrets = List(secretsArr.length()) { i ->
|
|
63
|
-
val s = secretsArr.getJSONObject(i)
|
|
64
|
-
ZkapSecret(sub = s.getString("sub"), iss = s.getString("iss"), aud = s.getString("aud"))
|
|
65
|
-
}
|
|
66
|
-
val result = generateAnchor(config, secrets)
|
|
67
|
-
JSONObject().put("evaluations", JSONArray(result.evaluations)).toString()
|
|
68
|
-
} catch (e: ZkapException) {
|
|
69
|
-
throw ZkapError(e.message ?: "ZkapException")
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
AsyncFunction("prove") { inputJson: String ->
|
|
74
|
-
try {
|
|
75
|
-
val obj = JSONObject(inputJson)
|
|
76
|
-
val config = parseConfig(obj.getJSONObject("config"))
|
|
77
|
-
val req = obj.getJSONObject("request")
|
|
78
|
-
|
|
79
|
-
val jwtsArr = req.getJSONArray("jwts")
|
|
80
|
-
val jwts = List(jwtsArr.length()) { jwtsArr.getString(it) }
|
|
81
|
-
|
|
82
|
-
val pkOpsArr = req.getJSONArray("pk_ops")
|
|
83
|
-
val pkOps = List(pkOpsArr.length()) { pkOpsArr.getString(it) }
|
|
84
|
-
|
|
85
|
-
val merklePathsArr = req.getJSONArray("merkle_paths")
|
|
86
|
-
val merklePaths = List(merklePathsArr.length()) { i ->
|
|
87
|
-
val inner = merklePathsArr.getJSONArray(i)
|
|
88
|
-
List(inner.length()) { j -> inner.getString(j) }
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
val leafIndicesArr = req.getJSONArray("leaf_indices")
|
|
92
|
-
val leafIndices = List(leafIndicesArr.length()) { leafIndicesArr.getLong(it).toULong() }
|
|
93
|
-
|
|
94
|
-
val anchorEvalsArr = req.getJSONArray("anchor_evals")
|
|
95
|
-
val anchorEvals = List(anchorEvalsArr.length()) { anchorEvalsArr.getString(it) }
|
|
96
|
-
|
|
97
|
-
val audHashListArr = req.getJSONArray("aud_hash_list")
|
|
98
|
-
val audHashList = List(audHashListArr.length()) { audHashListArr.getString(it) }
|
|
99
|
-
|
|
100
|
-
val request = ZkapProofRequest(
|
|
101
|
-
pkPath = req.getString("pk_path"),
|
|
102
|
-
jwts = jwts,
|
|
103
|
-
pkOps = pkOps,
|
|
104
|
-
merklePaths = merklePaths,
|
|
105
|
-
leafIndices = leafIndices,
|
|
106
|
-
root = req.getString("root"),
|
|
107
|
-
anchorEvals = anchorEvals,
|
|
108
|
-
hanchor = req.getString("hanchor"),
|
|
109
|
-
hSignUserOp = req.getString("h_sign_user_op"),
|
|
110
|
-
random = req.getString("random"),
|
|
111
|
-
audHashList = audHashList
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
val output = prove(config, request)
|
|
115
|
-
|
|
116
|
-
val proofsArr = JSONArray()
|
|
117
|
-
for (proofList in output.proofs) {
|
|
118
|
-
proofsArr.put(JSONArray(proofList))
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
JSONObject()
|
|
122
|
-
.put("proofs", proofsArr)
|
|
123
|
-
.put("shared_inputs", JSONArray(output.sharedInputs))
|
|
124
|
-
.put("partial_rhs_list", JSONArray(output.partialRhsList))
|
|
125
|
-
.put("jwt_exp_list", JSONArray(output.jwtExpList))
|
|
126
|
-
.toString()
|
|
127
|
-
} catch (e: ZkapException) {
|
|
128
|
-
throw ZkapError(e.message ?: "ZkapException")
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
private fun parseConfig(obj: JSONObject): ZkapCircuitConfig {
|
|
134
|
-
val claimsArr = obj.getJSONArray("claims")
|
|
135
|
-
return ZkapCircuitConfig(
|
|
136
|
-
maxJwtB64Len = obj.getLong("max_jwt_b64_len").toULong(),
|
|
137
|
-
maxPayloadB64Len = obj.getLong("max_payload_b64_len").toULong(),
|
|
138
|
-
maxAudLen = obj.getLong("max_aud_len").toULong(),
|
|
139
|
-
maxExpLen = obj.getLong("max_exp_len").toULong(),
|
|
140
|
-
maxIssLen = obj.getLong("max_iss_len").toULong(),
|
|
141
|
-
maxNonceLen = obj.getLong("max_nonce_len").toULong(),
|
|
142
|
-
maxSubLen = obj.getLong("max_sub_len").toULong(),
|
|
143
|
-
n = obj.getLong("n").toULong(),
|
|
144
|
-
k = obj.getLong("k").toULong(),
|
|
145
|
-
treeHeight = obj.getLong("tree_height").toULong(),
|
|
146
|
-
numAudienceLimit = obj.getLong("num_audience_limit").toULong(),
|
|
147
|
-
claims = List(claimsArr.length()) { claimsArr.getString(it) },
|
|
148
|
-
forbiddenString = obj.getString("forbidden_string")
|
|
149
|
-
)
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
class ZkapError(message: String) : Exception("[zkap] $message")
|