@nori-zk/proof-conversion-utils 0.5.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 ADDED
@@ -0,0 +1,441 @@
1
+ # @nori-zk/proof-conversion-utils
2
+
3
+ WebAssembly utilities for converting zero-knowledge proofs between different formats, with a focus on targeting Mina Protocol's o1js framework.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @nori-zk/proof-conversion-utils
9
+ ```
10
+
11
+ ## Overview
12
+
13
+ This package provides utilities to assist witness creation and alpha-beta pairing. As well as converting Groth16 zero-knowledge proofs from various sources (SnarkJS, SP1) into the format required by o1js for verification in Mina Protocol zkApps.
14
+
15
+ ## TypeScript API
16
+
17
+ ### Types
18
+
19
+ #### `AffinePoint2d`
20
+ A 2D affine point with x and y coordinates.
21
+
22
+ Each coordinate is a decimal string representing a large integer (BigInt in JS).
23
+ For example, 254-bit integers when using the BN254 curve.
24
+
25
+ Used for G1 curve points in affine form (no z coordinate).
26
+
27
+ ```typescript
28
+ interface AffinePoint2d {
29
+ x: string; // String representation of x coordinate
30
+ y: string; // String representation of y coordinate
31
+ }
32
+ ```
33
+
34
+ #### `ComplexAffinePoint2d`
35
+ A 2D affine point with complex coordinates (each coordinate has real and imaginary parts).
36
+
37
+ x = (x_c0, x_c1) and y = (y_c0, y_c1), where c0 is real and c1 is imaginary.
38
+ Each component is a decimal string representing a large integer (BigInt in JS).
39
+ For example, 254-bit integers when using the BN254 curve.
40
+
41
+ Used for G2 curve points in affine form (no z coordinate).
42
+
43
+ ```typescript
44
+ interface ComplexAffinePoint2d {
45
+ x_c0: string; // Real part of x coordinate
46
+ x_c1: string; // Imaginary part of x coordinate
47
+ y_c0: string; // Real part of y coordinate
48
+ y_c1: string; // Imaginary part of y coordinate
49
+ }
50
+ ```
51
+
52
+ #### `ProjectivePoint`
53
+ Represents a projective point with x, y, z coordinates.
54
+
55
+ Each coordinate is a decimal string representing a large integer (BigInt in JS).
56
+ For example, 254-bit integers when using the BN254 curve.
57
+
58
+ Used for G1 curve points in projective form as output by snarkjs.
59
+
60
+ ```typescript
61
+ export type ProjectivePoint = [string, string, string];
62
+ ```
63
+
64
+ #### `ComplexProjectivePoint`
65
+ A projective point with complex coordinates.
66
+
67
+ Each coordinate has real (c0) and imaginary (c1) parts.
68
+ Each component is a decimal string representing a large integer (BigInt in JS).
69
+
70
+ Used for G2 curve points in projective form as output by snarkjs.
71
+
72
+ ```typescript
73
+ export type ComplexProjectivePoint = [[string, string], [string, string], [string, string]];
74
+ ```
75
+
76
+ #### `Field12`
77
+ A 12-element field value (Fq12) serialized as decimal strings.
78
+ Used for pairing outputs like `alpha_beta` and `w27` in verification keys.
79
+
80
+ ##### Structure
81
+
82
+ Fq12 is built from a \'tower\' of field extensions:
83
+ - **Fq**: A single 254-bit integer (the base field)
84
+ - **Fq2**: Two Fq values (real + imaginary)
85
+ - **Fq6**: Three Fq2 values
86
+ - **Fq12**: Two Fq6 values (`g` and `h` in our serialization)
87
+
88
+ So: Fq12 = 2 × Fq6 = 2 × 3 × Fq2 = 12 base field elements.
89
+
90
+ ##### Naming Convention
91
+ `{group}{pair}{component}`:
92
+ - group: `g` or `h`
93
+ - pair: `0`, `1`, or `2` (which pair within the group)
94
+ - component: `0` (real) or `1` (imaginary)
95
+
96
+ ```typescript
97
+ interface Field12 {
98
+ g00: string;
99
+ g01: string;
100
+ g10: string;
101
+ g11: string;
102
+ g20: string;
103
+ g21: string;
104
+ h00: string;
105
+ h01: string;
106
+ h10: string;
107
+ h11: string;
108
+ h20: string;
109
+ h21: string;
110
+ }
111
+ ```
112
+
113
+ #### `PairingInput`
114
+ Input for computing a pairing operation.
115
+
116
+ A pairing combines a G1 point and a G2 point to produce a 12-element field value.
117
+ In Groth16/PLONK verification keys, this is used to precompute e(alpha, beta).
118
+
119
+ - `alpha`: G1 curve point (simple 2D coordinates)
120
+ - `beta`: G2 curve point (complex 2D coordinates, each coordinate is a pair)
121
+
122
+ ```typescript
123
+ interface PairingInput {
124
+ alpha: AffinePoint2d;
125
+ beta: ComplexAffinePoint2d;
126
+ }
127
+ ```
128
+
129
+ #### `AuxWitness`
130
+ Auxiliary witness for pairing verification.
131
+
132
+ Contains precomputed hints for efficient final exponentiation:
133
+ - `c`: A 12-element field value
134
+ - `shift_power`: A small integer (0, 1, or 2) for the shift factor
135
+
136
+ ```typescript
137
+ interface AuxWitness {
138
+ c: Field12;
139
+ shift_power: string; // '0', '1', or '2'
140
+ }
141
+ ```
142
+
143
+ #### `O1jsProof`
144
+ Groth16 proof in o1js format.
145
+
146
+ Contains the three proof curve points plus public inputs:
147
+ - `negA`: Negated A point (G1)
148
+ - `B`: B point (G2 - complex coordinates)
149
+ - `C`: C point (G1)
150
+ - `pi1` through `pi6`: Public inputs (max 6 supported)
151
+
152
+ ```typescript
153
+ interface O1jsProof {
154
+ negA: AffinePoint2d; // Negated A point (G1)
155
+ B: ComplexAffinePoint2d; // B point (G2)
156
+ C: AffinePoint2d; // C point (G1)
157
+ pi1?: string; // Public input 1 (optional)
158
+ pi2?: string; // Public input 2 (optional)
159
+ pi3?: string; // Public input 3 (optional)
160
+ pi4?: string; // Public input 4 (optional)
161
+ pi5?: string; // Public input 5 (optional)
162
+ pi6?: string; // Public input 6 (optional)
163
+ }
164
+ ```
165
+
166
+ #### `O1jsVK`
167
+ Groth16 verification key in o1js format.
168
+
169
+ Contains the verification key parameters needed for proof verification:
170
+ - `alpha`: Alpha point from trusted setup (G1)
171
+ - `beta`, `gamma`, `delta`: Curve points from the trusted setup (G2)
172
+ - `alpha_beta`: Precomputed pairing e(alpha, beta) as a 12-element field value
173
+ - `w27`: A 27th root of unity used for pairing optimizations
174
+ - `ic0` through `ic6`: Input commitment points for public input verification.
175
+ `ic0` is always present (the constant term). `ic1`-`ic6` are optional based on how many public inputs the circuit has (max 6 supported).
176
+
177
+ The Groth16 verification equation uses: `PI = ic0 + Σ(public_input[i] * ic[i+1])`
178
+
179
+ ```typescript
180
+ interface O1jsVK {
181
+ alpha: AffinePoint2d;
182
+ beta: ComplexAffinePoint2d;
183
+ gamma: ComplexAffinePoint2d;
184
+ delta: ComplexAffinePoint2d;
185
+ alpha_beta: Field12; // Precomputed pairing e(α, β)
186
+ w27: Field12; // 27th root of unity for pairing optimizations
187
+ ic0: AffinePoint2d; // Constant term (always present)
188
+ ic1?: AffinePoint2d; // Optional IC points based on circuit
189
+ ic2?: AffinePoint2d;
190
+ ic3?: AffinePoint2d;
191
+ ic4?: AffinePoint2d;
192
+ ic5?: AffinePoint2d;
193
+ ic6?: AffinePoint2d;
194
+ }
195
+ ```
196
+
197
+ #### `O1jsGroth16`
198
+ Groth16 proof and verification key in o1js format.
199
+
200
+ Contains both the converted proof and verification key ready for verification in Mina using o1js.
201
+
202
+
203
+ ```typescript
204
+ interface O1jsGroth16 {
205
+ proof: O1jsProof;
206
+ vk: O1jsVK;
207
+ }
208
+ ```
209
+
210
+ #### `SnarkjsProof`
211
+ Groth16 proof in snarkjs/circom format.
212
+
213
+ This is the input format produced by snarkjs when generating proofs.
214
+ Points are in projective coordinates (with z component).
215
+
216
+ - `pi_a`: A point (G1 projective)
217
+ - `pi_b`: B point (G2 projective)
218
+ - `pi_c`: C point (G1 projective)
219
+
220
+ ```typescript
221
+ interface SnarkjsProof {
222
+ pi_a: [string, string, string]; // A point in G1 projective
223
+ pi_b: [[string, string], [string, string], [string, string]]; // B point in G2 projective
224
+ pi_c: [string, string, string]; // C point in G1 projective
225
+ }
226
+ ```
227
+
228
+ #### `SnarkjsVK`
229
+ Groth16 verification key in snarkjs/circom format.
230
+
231
+ This is the input format produced by snarkjs when compiling circom circuits.
232
+ Points are in projective coordinates (with z component).
233
+
234
+ - `nPublic`: Number of public inputs in the circuit
235
+ - `vk_alpha_1`: Alpha point (G1 projective)
236
+ - `vk_beta_2`, `vk_gamma_2`, `vk_delta_2`: Setup points (G2 projective)
237
+ - `IC`: Input commitment points, one per public input plus a constant term
238
+
239
+
240
+ ```typescript
241
+ interface SnarkjsVK {
242
+ nPublic: number;
243
+ vk_alpha_1: [string, string, string];
244
+ vk_beta_2: [[string, string], [string, string], [string, string]];
245
+ vk_gamma_2: [[string, string], [string, string], [string, string]];
246
+ vk_delta_2: [[string, string], [string, string], [string, string]];
247
+ vk_alphabeta_12: [[string, string], [string, string], [string, string]];
248
+ IC: Array<[string, string, string]>;
249
+ }
250
+ ```
251
+
252
+ #### `Groth16Bn254Proof`
253
+ Groth16 proof in SP1/gnark format.
254
+ Mirrors `sp1_prover::Groth16Bn254Proof`.
255
+
256
+ ```typescript
257
+ export interface Groth16Bn254Proof {
258
+ public_inputs: [string, string];
259
+ encoded_proof: string;
260
+ raw_proof: string;
261
+ groth16_vkey_hash: number[];
262
+ }
263
+ ```
264
+
265
+ #### `PlonkBn254Proof`
266
+ Plonk proof in SP1/gnark format.
267
+ Mirrors `sp1_prover::PlonkBn254Proof`.
268
+
269
+ ```typescript
270
+ export interface PlonkBn254Proof {
271
+ public_inputs: [string, string];
272
+ encoded_proof: string;
273
+ raw_proof: string;
274
+ plonk_vkey_hash: number[];
275
+ }
276
+ ```
277
+
278
+ #### `SP1Proof`
279
+ SP1 proof enum containing different proof types.
280
+ Mirrors `sp1_stark::SP1Proof`.
281
+
282
+ ```typescript
283
+ export type SP1Proof = { Groth16: Groth16Bn254Proof } | { Plonk: PlonkBn254Proof };
284
+ ```
285
+
286
+ #### `SP1PublicValues`
287
+ SP1 public values.
288
+ Mirrors `sp1_primitives::io::SP1PublicValues`.
289
+
290
+ ```typescript
291
+ export interface SP1PublicValues {
292
+ buffer: SP1Buffer;
293
+ }
294
+
295
+ #### `SP1ProofWithPublicValues`
296
+ SP1 proof with public values.
297
+ Mirrors `sp1_sdk::proof::SP1ProofWithPublicValues`.
298
+
299
+ ```typescript
300
+ export interface SP1ProofWithPublicValues {
301
+ proof: SP1Proof;
302
+ public_values: SP1PublicValues;
303
+ sp1_version: string;
304
+ tee_proof: number[] | null;
305
+ }
306
+ ```
307
+
308
+ ### Functions
309
+
310
+ #### `compute_pairing(input: PairingInput): Field12`
311
+
312
+ Computes a pairing for a verification key.
313
+
314
+ Takes two curve points (alpha and beta from the trusted setup) and computes their pairing using the Miller loop algorithm. The result is a 12-element field value that gets stored in the verification key.
315
+
316
+ ```typescript
317
+ const result = compute_pairing({
318
+ alpha: { x: '...', y: '...' },
319
+ beta: { x_c0: '...', x_c1: '...', y_c0: '...', y_c1: '...' }
320
+ });
321
+ ```
322
+
323
+ #### `compute_aux_witness(input: Field12): AuxWitness`
324
+
325
+ Computes the auxiliary witness from a Miller loop output.
326
+
327
+ Takes a 12-element field value (the result of a Miller loop pairing computation) and computes the auxiliary witness needed for efficient verification.
328
+
329
+ ```typescript
330
+ const auxWitness = compute_aux_witness({
331
+ g00: '...', g01: '...', g10: '...', g11: '...', g20: '...', g21: '...',
332
+ h00: '...', h01: '...', h10: '...', h11: '...', h20: '...', h21: '...'
333
+ });
334
+ ```
335
+
336
+ #### `convert_snarkjs_groth16_to_o1js(proof: SnarkjsProof, public_inputs: string[], vk: SnarkjsVK): O1jsGroth16`
337
+
338
+ Converts a SnarkJS/Circom Groth16 proof and verification key to o1js format.
339
+
340
+ This function takes Groth16 proofs generated by snarkjs (the JavaScript implementation of Groth16 commonly used with circom circuits) and converts them to o1js format for verification in Mina Protocol zkApps.
341
+
342
+ **Key Conversions:**
343
+ - The A point (`pi_a`) is negated for o1js compatibility
344
+ - Points are converted from projective coordinates to affine form
345
+ - The `alpha_beta` pairing e(α, β) is precomputed
346
+ - Supports up to 6 public inputs
347
+
348
+ ```typescript
349
+ import { convert_snarkjs_groth16_to_o1js } from '@nori-zk/proof-conversion-utils';
350
+
351
+ const o1jsFormat = convert_snarkjs_groth16_to_o1js(
352
+ snarkjsProof,
353
+ ['123', '456'], // Public inputs as strings
354
+ snarkjsVK
355
+ );
356
+ ```
357
+
358
+ #### `convert_sp1_groth16_to_o1js(sp1_proof: SP1ProofWithPublicValues): O1jsGroth16`
359
+
360
+ Converts an SP1 Groth16 proof to o1js format.
361
+
362
+ This function takes Groth16 proofs generated by SP1 (Succinct's zkVM) and converts them to o1js format for verification in Mina Protocol zkApps. SP1 uses gnark's Groth16 implementation internally.
363
+
364
+ **Key Features:**
365
+ - Automatically decompresses gnark-formatted proof bytes
366
+ - Uses the embedded SP1 v5.0.0 verification key (all SP1 Groth16 proofs use the same VK)
367
+ - Negates the A point for o1js compatibility
368
+ - SP1 Groth16 proofs always have exactly 2 public inputs (vkey_hash and public_values_hash)
369
+
370
+ ```typescript
371
+ import { convert_sp1_groth16_to_o1js } from '@nori-zk/proof-conversion-utils';
372
+
373
+ const o1jsFormat = convert_sp1_groth16_to_o1js(sp1Proof);
374
+ ```
375
+
376
+ ## Usage Examples
377
+
378
+ ### Converting SnarkJS Proof
379
+
380
+ ```typescript
381
+ import { convert_snarkjs_groth16_to_o1js } from '@nori-zk/proof-conversion-utils';
382
+ import snarkjsProof from './proof.json';
383
+ import snarkjsVK from './verification_key.json';
384
+
385
+ const publicInputs = ['12345', '67890'];
386
+
387
+ const { proof, vk } = convert_snarkjs_groth16_to_o1js(
388
+ snarkjsProof,
389
+ publicInputs,
390
+ snarkjsVK
391
+ );
392
+
393
+ // Use proof and vk with o1js for verification in Mina
394
+ ```
395
+
396
+ ### Converting SP1 Proof
397
+
398
+ ```typescript
399
+ import { convert_sp1_groth16_to_o1js } from '@nori-zk/proof-conversion-utils';
400
+ import sp1Proof from './sp1_proof.json';
401
+
402
+ const { proof, vk } = convert_sp1_groth16_to_o1js(sp1Proof);
403
+
404
+ // Use proof and vk with o1js for verification in Mina
405
+ ```
406
+
407
+ ### Computing Pairing
408
+
409
+ ```typescript
410
+ import { compute_pairing } from '@nori-zk/proof-conversion-utils';
411
+
412
+ const alphaBeta = compute_pairing({
413
+ alpha: {
414
+ x: '12369698276624038106972479882730964985390333465481074863680349672529458504727',
415
+ y: '15615049479232918185966644204891621024197935236528708875381357850359187990605'
416
+ },
417
+ beta: {
418
+ x_c0: '1903903027629957495668852277947233956036752695749808956450499753161040073874',
419
+ x_c1: '19516214232409959981032970092985844340835031525223058295881548971699867691648',
420
+ y_c0: '19307974034844496356197776793106808222110218706117190747312969862440532637662',
421
+ y_c1: '13697410665674063166131807846290149764118701671708810697019074013384033689104'
422
+ }
423
+ });
424
+ ```
425
+
426
+ ## Supported Formats
427
+
428
+ - **SnarkJS**: Groth16 proofs from snarkjs/circom circuits
429
+ - **SP1**: Groth16 proofs from SP1 v5.0.0 zkVM
430
+ - **o1js**: Target format for Mina Protocol zkApps
431
+
432
+ ## Technical Details
433
+
434
+ - Built with Rust and compiled to WebAssembly for high performance
435
+ - Uses the arkworks cryptography library for BN254 curve operations
436
+ - All field elements are represented as strings for JavaScript compatibility
437
+ - Supports BN254 elliptic curve pairing
438
+
439
+ ## License
440
+
441
+ Apache-2.0
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@nori-zk/proof-conversion-utils",
3
+ "type": "module",
4
+ "version": "0.5.0",
5
+ "license": "Apache-2.0",
6
+ "publishConfig": {
7
+ "registry": "https://registry.npmjs.org/",
8
+ "access": "public"
9
+ },
10
+ "files": [
11
+ "pairing_utils_bg.wasm",
12
+ "pairing_utils.js",
13
+ "pairing_utils_bg.js",
14
+ "pairing_utils.d.ts",
15
+ "README.md"
16
+ ],
17
+ "main": "pairing_utils.js",
18
+ "types": "pairing_utils.d.ts",
19
+ "sideEffects": [
20
+ "./pairing_utils.js",
21
+ "./snippets/*"
22
+ ]
23
+ }
@@ -0,0 +1,466 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /**
4
+ * A 12-element field value (Fq12) serialized as decimal strings.
5
+ *
6
+ * Used for pairing outputs like `alpha_beta` and `w27` in verification keys.
7
+ *
8
+ * # Structure
9
+ *
10
+ * Fq12 is built from a \"tower\" of field extensions:
11
+ * - **Fq**: A single 254-bit integer (the base field)
12
+ * - **Fq2**: Two Fq values (real + imaginary)
13
+ * - **Fq6**: Three Fq2 values
14
+ * - **Fq12**: Two Fq6 values (`g` and `h` in our serialization)
15
+ *
16
+ * So: Fq12 = 2 × Fq6 = 2 × 3 × Fq2 = 12 base field elements.
17
+ *
18
+ * # Naming Convention
19
+ *
20
+ * `{group}{pair}{component}`:
21
+ * - group: `g` or `h`
22
+ * - pair: `0`, `1`, or `2` (which pair within the group)
23
+ * - component: `0` (real) or `1` (imaginary)
24
+ */
25
+ export interface Field12 {
26
+ g00: string;
27
+ g01: string;
28
+ g10: string;
29
+ g11: string;
30
+ g20: string;
31
+ g21: string;
32
+ h00: string;
33
+ h01: string;
34
+ h10: string;
35
+ h11: string;
36
+ h20: string;
37
+ h21: string;
38
+ }
39
+
40
+ /**
41
+ * A 2D affine point with complex coordinates (each coordinate has real and imaginary parts).
42
+ *
43
+ * x = (x_c0, x_c1) and y = (y_c0, y_c1), where c0 is real and c1 is imaginary.
44
+ * Each component is a decimal string representing a large integer (BigInt in JS).
45
+ * For example, 254-bit integers when using the BN254 curve.
46
+ *
47
+ * Used for G2 curve points in affine form (no z coordinate).
48
+ */
49
+ export interface ComplexAffinePoint2d {
50
+ x_c0: string;
51
+ x_c1: string;
52
+ y_c0: string;
53
+ y_c1: string;
54
+ }
55
+
56
+ /**
57
+ * A 2D affine point with x and y coordinates.
58
+ *
59
+ * Each coordinate is a decimal string representing a large integer (BigInt in JS).
60
+ * For example, 254-bit integers when using the BN254 curve.
61
+ *
62
+ * Used for G1 curve points in affine form (no z coordinate).
63
+ */
64
+ export interface AffinePoint2d {
65
+ x: string;
66
+ y: string;
67
+ }
68
+
69
+ /**
70
+ * A projective point with complex coordinates.
71
+ *
72
+ * Each coordinate has real (c0) and imaginary (c1) parts.
73
+ * Each component is a decimal string representing a large integer (BigInt in JS).
74
+ *
75
+ * Used for G2 curve points in projective form as output by snarkjs.
76
+ * Deserializes from nested array format: `[[x_c0, x_c1], [y_c0, y_c1], [z_c0, z_c1]]`.
77
+ */
78
+ export type ComplexProjectivePoint = [[string, string], [string, string], [string, string]];
79
+
80
+ /**
81
+ * A projective point with x, y, z coordinates.
82
+ *
83
+ * Each coordinate is a decimal string representing a large integer (BigInt in JS).
84
+ * For example, 254-bit integers when using the BN254 curve.
85
+ *
86
+ * Used for G1 curve points in projective form as output by snarkjs.
87
+ * Deserializes from array format: `[\"x\", \"y\", \"z\"]`.
88
+ */
89
+ export type ProjectivePoint = [string, string, string];
90
+
91
+ /**
92
+ * Auxiliary witness for pairing verification.
93
+ *
94
+ * Contains precomputed hints for efficient final exponentiation:
95
+ * - `c`: A 12-element field value
96
+ * - `shift_power`: A small integer (0, 1, or 2) for the shift factor
97
+ */
98
+ export interface AuxWitness {
99
+ c: Field12;
100
+ shift_power: string;
101
+ }
102
+
103
+ /**
104
+ * Buffer containing public values data.
105
+ */
106
+ export interface SP1Buffer {
107
+ data: number[];
108
+ }
109
+
110
+ /**
111
+ * Groth16 proof and verification key in o1js format.
112
+ *
113
+ * Contains both the converted proof and verification key ready for
114
+ * verification in Mina using o1js.
115
+ */
116
+ export interface O1jsGroth16 {
117
+ proof: O1jsProof;
118
+ vk: O1jsVK;
119
+ }
120
+
121
+ /**
122
+ * Groth16 proof in SP1/gnark format.
123
+ *
124
+ * Mirrors `sp1_prover::Groth16Bn254Proof`.
125
+ */
126
+ export interface Groth16Bn254Proof {
127
+ public_inputs: [string, string];
128
+ encoded_proof: string;
129
+ raw_proof: string;
130
+ groth16_vkey_hash: number[];
131
+ }
132
+
133
+ /**
134
+ * Groth16 proof in o1js format.
135
+ *
136
+ * Contains the three proof curve points plus public inputs:
137
+ * - `negA`: Negated A point (G1)
138
+ * - `B`: B point (G2 - complex coordinates)
139
+ * - `C`: C point (G1)
140
+ * - `pi1` through `pi6`: Public inputs (max 6 supported)
141
+ */
142
+ export interface O1jsProof {
143
+ negA: AffinePoint2d;
144
+ B: ComplexAffinePoint2d;
145
+ C: AffinePoint2d;
146
+ pi1?: string;
147
+ pi2?: string;
148
+ pi3?: string;
149
+ pi4?: string;
150
+ pi5?: string;
151
+ pi6?: string;
152
+ }
153
+
154
+ /**
155
+ * Groth16 proof in snarkjs/circom format.
156
+ *
157
+ * This is the input format produced by snarkjs when generating proofs.
158
+ * Points are in projective coordinates (with z component).
159
+ *
160
+ * - `pi_a`: A point (G1 projective)
161
+ * - `pi_b`: B point (G2 projective)
162
+ * - `pi_c`: C point (G1 projective)
163
+ */
164
+ export interface SnarkjsProof {
165
+ pi_a: ProjectivePoint;
166
+ pi_b: ComplexProjectivePoint;
167
+ pi_c: ProjectivePoint;
168
+ }
169
+
170
+ /**
171
+ * Groth16 verification key in o1js format.
172
+ *
173
+ * Contains the verification key parameters needed for proof verification:
174
+ *
175
+ * - `alpha`: Alpha point from trusted setup (G1)
176
+ * - `beta`, `gamma`, `delta`: Curve points from the trusted setup (G2)
177
+ * - `alpha_beta`: Precomputed pairing e(alpha, beta) as a 12-element field value
178
+ * - `w27`: A 27th root of unity used for pairing optimizations
179
+ * - `ic0` through `ic6`: Input commitment points for public input verification.
180
+ * `ic0` is always present (the constant term). `ic1`-`ic6` are optional based on
181
+ * how many public inputs the circuit has (max 6 supported).
182
+ *
183
+ * The Groth16 verification equation uses: `PI = ic0 + Σ(public_input[i] * ic[i+1])`
184
+ */
185
+ export interface O1jsVK {
186
+ alpha: AffinePoint2d;
187
+ beta: ComplexAffinePoint2d;
188
+ gamma: ComplexAffinePoint2d;
189
+ delta: ComplexAffinePoint2d;
190
+ alpha_beta: Field12;
191
+ w27: Field12;
192
+ ic0: AffinePoint2d;
193
+ ic1?: AffinePoint2d;
194
+ ic2?: AffinePoint2d;
195
+ ic3?: AffinePoint2d;
196
+ ic4?: AffinePoint2d;
197
+ ic5?: AffinePoint2d;
198
+ ic6?: AffinePoint2d;
199
+ }
200
+
201
+ /**
202
+ * Groth16 verification key in snarkjs/circom format.
203
+ *
204
+ * This is the input format produced by snarkjs when compiling circom circuits.
205
+ * Points are in projective coordinates (with z component).
206
+ *
207
+ * - `n_public`: Number of public inputs in the circuit
208
+ * - `vk_alpha_1`: Alpha point (G1 projective)
209
+ * - `vk_beta_2`, `vk_gamma_2`, `vk_delta_2`: Setup points (G2 projective)
210
+ * - `ic`: Input commitment points, one per public input plus a constant term
211
+ */
212
+ export interface SnarkjsVK {
213
+ nPublic: number;
214
+ vk_alpha_1: ProjectivePoint;
215
+ vk_beta_2: ComplexProjectivePoint;
216
+ vk_gamma_2: ComplexProjectivePoint;
217
+ vk_delta_2: ComplexProjectivePoint;
218
+ IC: ProjectivePoint[];
219
+ }
220
+
221
+ /**
222
+ * Input for computing a pairing operation.
223
+ *
224
+ * A pairing combines a G1 point and a G2 point to produce a 12-element field value.
225
+ * In Groth16/PLONK verification keys, this is used to precompute e(alpha, beta).
226
+ *
227
+ * - `alpha`: G1 curve point (simple 2D coordinates)
228
+ * - `beta`: G2 curve point (complex 2D coordinates, each coordinate is a pair)
229
+ *
230
+ * See [`compute_pairing`] for the computation.
231
+ */
232
+ export interface PairingInput {
233
+ alpha: AffinePoint2d;
234
+ beta: ComplexAffinePoint2d;
235
+ }
236
+
237
+ /**
238
+ * Plonk proof in SP1/gnark format.
239
+ *
240
+ * Mirrors `sp1_prover::PlonkBn254Proof`.
241
+ */
242
+ export interface PlonkBn254Proof {
243
+ public_inputs: [string, string];
244
+ encoded_proof: string;
245
+ raw_proof: string;
246
+ plonk_vkey_hash: number[];
247
+ }
248
+
249
+ /**
250
+ * SP1 proof enum containing different proof types.
251
+ *
252
+ * Mirrors `sp1_stark::SP1Proof`.
253
+ */
254
+ export type SP1Proof = { Groth16: Groth16Bn254Proof } | { Plonk: PlonkBn254Proof };
255
+
256
+ /**
257
+ * SP1 proof with public values.
258
+ *
259
+ * Mirrors `sp1_sdk::proof::SP1ProofWithPublicValues`.
260
+ */
261
+ export interface SP1ProofWithPublicValues {
262
+ proof: SP1Proof;
263
+ public_values: SP1PublicValues;
264
+ sp1_version: string;
265
+ tee_proof: number[] | null;
266
+ }
267
+
268
+ /**
269
+ * SP1 public values.
270
+ *
271
+ * Mirrors `sp1_primitives::io::SP1PublicValues`.
272
+ */
273
+ export interface SP1PublicValues {
274
+ buffer: SP1Buffer;
275
+ }
276
+
277
+
278
+ /**
279
+ * Computes the auxiliary witness from a Miller loop output.
280
+ *
281
+ * # What This Does
282
+ *
283
+ * Takes a 12-element field value (the result of a Miller loop pairing computation)
284
+ * and computes the auxiliary witness needed for efficient verification.
285
+ *
286
+ * The Miller loop is the first step of pairing-based verification. Its output
287
+ * needs further processing (final exponentiation), which is expensive. The
288
+ * auxiliary witness provides precomputed hints that make this step efficient.
289
+ *
290
+ * # Input
291
+ *
292
+ * A JS object matching [`Field12`] structure (12 string fields: g00-g21, h00-h21).
293
+ *
294
+ * # Output
295
+ *
296
+ * A JS object matching [`AuxWitness`] structure containing:
297
+ * - `c`: A 12-element field value
298
+ * - `shift_power`: "0", "1", or "2"
299
+ *
300
+ * # Panics
301
+ *
302
+ * Panics if the input is not a valid Miller loop output (fails internal assertion).
303
+ */
304
+ export function compute_aux_witness(input: Field12): AuxWitness;
305
+
306
+ /**
307
+ * Computes a pairing for a verification key.
308
+ *
309
+ * # What This Does
310
+ *
311
+ * Takes two curve points (alpha and beta from the trusted setup) and computes
312
+ * their pairing using the Miller loop algorithm. The result is a 12-element
313
+ * field value that gets stored in the verification key.
314
+ *
315
+ * This pairing e(alpha, beta) is constant for a given verification key, so it's
316
+ * precomputed once and reused for all proof verifications.
317
+ *
318
+ * # Input
319
+ *
320
+ * A JS object matching [`PairingInput`] structure:
321
+ * - `alpha`: An [`AffinePoint2d`] with `x` and `y` fields
322
+ * - `beta`: A [`ComplexAffinePoint2d`] with `x_c0`, `x_c1`, `y_c0`, `y_c1` fields
323
+ *
324
+ * # Output
325
+ *
326
+ * A JS object matching [`Field12`] structure (12 string fields: g00-g21, h00-h21).
327
+ *
328
+ * # Errors
329
+ *
330
+ * Returns a JS error if input parsing or coordinate conversion fails.
331
+ */
332
+ export function compute_pairing(input: PairingInput): Field12;
333
+
334
+ /**
335
+ * Converts a snarkjs/circom Groth16 proof and verification key to o1js format.
336
+ *
337
+ * This function takes Groth16 proofs generated by snarkjs (the JavaScript implementation
338
+ * of Groth16 commonly used with circom circuits) and converts them to o1js format for
339
+ * verification in Mina Protocol zkApps.
340
+ *
341
+ * # Conversion Details
342
+ *
343
+ * ## Proof Conversion
344
+ * - The A point (`pi_a`) is **negated** for o1js compatibility. The o1js verification
345
+ * equation uses `-A` rather than `A` in the pairing check.
346
+ * - Points are converted from projective coordinates (with z component) to affine form.
347
+ * - The B point is a G2 point with complex coordinates (x_c0, x_c1, y_c0, y_c1).
348
+ * - The C point is a G1 point with simple coordinates (x, y).
349
+ *
350
+ * ## Verification Key Conversion
351
+ * - All curve points are converted from projective to affine form.
352
+ * - The `alpha_beta` pairing e(α, β) is computed using arkworks `multi_miller_loop`.
353
+ * This is a constant for each VK and is precomputed to save verification time.
354
+ * - A hardcoded `w27` (27th root of unity) is added for pairing optimizations.
355
+ * See https://eprint.iacr.org/2024/640 for the optimization technique.
356
+ * - IC (input commitment) points are mapped to ic0-ic6 fields.
357
+ *
358
+ * ## Validation
359
+ * - The `nPublic` field in the VK must match the number of public inputs provided.
360
+ * - The IC array length must equal nPublic + 1 (ic0 is the constant term).
361
+ *
362
+ * # Input Format
363
+ *
364
+ * - `proof`: snarkjs proof JSON object with:
365
+ * - `pi_a`: `[x, y, z]` - A point in G1 projective coordinates
366
+ * - `pi_b`: `[[x_c0, x_c1], [y_c0, y_c1], [z_c0, z_c1]]` - B point in G2 projective
367
+ * - `pi_c`: `[x, y, z]` - C point in G1 projective coordinates
368
+ *
369
+ * - `public_inputs`: Array of public input strings as decimal numbers, e.g., `["123", "456"]`.
370
+ * Maximum 6 public inputs are supported.
371
+ *
372
+ * - `vk`: snarkjs verification key JSON object with:
373
+ * - `nPublic`: Number of public inputs
374
+ * - `vk_alpha_1`: Alpha point (G1 projective)
375
+ * - `vk_beta_2`: Beta point (G2 projective)
376
+ * - `vk_gamma_2`: Gamma point (G2 projective)
377
+ * - `vk_delta_2`: Delta point (G2 projective)
378
+ * - `IC`: Array of IC points (G1 projective), length = nPublic + 1
379
+ *
380
+ * # Output Format
381
+ *
382
+ * Returns an [`O1jsGroth16`] object containing:
383
+ *
384
+ * - `proof`: o1js-formatted proof with:
385
+ * - `negA`: Negated A point `{x, y}` as decimal strings
386
+ * - `B`: B point `{x_c0, x_c1, y_c0, y_c1}` as decimal strings
387
+ * - `C`: C point `{x, y}` as decimal strings
388
+ * - `pi1` through `pi6`: Public inputs (only present if provided)
389
+ *
390
+ * - `vk`: o1js-formatted verification key with:
391
+ * - `alpha`, `beta`, `gamma`, `delta`: Curve points
392
+ * - `alpha_beta`: Precomputed pairing as 12-element Fq12 field
393
+ * - `w27`: 27th root of unity as 12-element Fq12 field
394
+ * - `ic0` through `ic6`: Input commitment points (only present if in VK)
395
+ *
396
+ * # Errors
397
+ *
398
+ * Returns an error if:
399
+ * - Input JSON parsing fails (invalid structure or types)
400
+ * - VK validation fails (`nPublic` doesn't match public inputs count, wrong IC length)
401
+ * - Point coordinate parsing fails (invalid field element strings)
402
+ * - More than 6 public inputs are provided
403
+ */
404
+ export function convert_snarkjs_groth16_to_o1js(proof: SnarkjsProof, public_inputs: string[], vk: SnarkjsVK): O1jsGroth16;
405
+
406
+ /**
407
+ * Converts an SP1 Groth16 proof to o1js format.
408
+ *
409
+ * This function takes Groth16 proofs generated by SP1 (Succinct's zkVM) and converts
410
+ * them to o1js format for verification in Mina Protocol zkApps. SP1 uses gnark's
411
+ * Groth16 implementation internally, which produces proofs in a compressed format
412
+ * that must be decompressed before conversion.
413
+ *
414
+ * # Conversion Details
415
+ *
416
+ * ## Proof Extraction & Decompression
417
+ * - The `encoded_proof` field contains hex-encoded gnark proof bytes.
418
+ * - The first 4 bytes of the proof are a vkey hash prefix (skipped during parsing).
419
+ * - gnark uses a compressed point format that differs from arkworks. This function
420
+ * decompresses G1 and G2 points using endianness conversion and flag translation.
421
+ * - The decompression follows the gnark → arkworks conversion from sp1-sui.
422
+ *
423
+ * ## Proof Conversion
424
+ * - The A point is **negated** for o1js compatibility. The o1js verification
425
+ * equation uses `-A` rather than `A` in the pairing check.
426
+ * - SP1 Groth16 proofs have exactly 2 public inputs (vkey_hash and public_values_hash).
427
+ *
428
+ * ## Verification Key
429
+ * - All SP1 v5.0.0 Groth16 proofs use the **same verification key**. This VK is
430
+ * embedded in the library (`GROTH16_VK_5_0_0_BYTES`) and loaded automatically.
431
+ * - The VK is decompressed from gnark format to arkworks format.
432
+ * - The `alpha_beta` pairing e(α, β) is computed and included in the output.
433
+ * - The hardcoded `w27` (27th root of unity) is added for pairing optimizations.
434
+ *
435
+ * # Input Format
436
+ *
437
+ * - `sp1_proof`: SP1ProofWithPublicValues JSON shim object representation
438
+ * - FIXME write an example here!
439
+ *
440
+ * # Output Format
441
+ *
442
+ * Returns an [`O1jsGroth16`] object containing:
443
+ *
444
+ * - `proof`: o1js-formatted proof with:
445
+ * - `negA`: Negated A point `{x, y}` as decimal strings
446
+ * - `B`: B point `{x_c0, x_c1, y_c0, y_c1}` as decimal strings
447
+ * - `C`: C point `{x, y}` as decimal strings
448
+ * - `pi1`: First public input (vkey_hash)
449
+ * - `pi2`: Second public input (public_values_hash)
450
+ *
451
+ * - `vk`: o1js-formatted SP1 v5.0.0 verification key with:
452
+ * - `alpha`, `beta`, `gamma`, `delta`: Curve points
453
+ * - `alpha_beta`: Precomputed pairing as 12-element Fq12 field
454
+ * - `w27`: 27th root of unity as 12-element Fq12 field
455
+ * - `ic0`, `ic1`, `ic2`: Input commitment points (SP1 VK has 3 IC points)
456
+ *
457
+ * # Errors
458
+ *
459
+ * Returns an error if:
460
+ * - Input JSON parsing fails (invalid structure or types)
461
+ * - Proof is not the `Groth16` variant (e.g., it's a PLONK proof)
462
+ * - Proof is empty (mock proof - not supported)
463
+ * - Hex decoding of `encoded_proof` fails
464
+ * - gnark point decompression fails (invalid curve points)
465
+ */
466
+ export function convert_sp1_groth16_to_o1js(sp1_proof: SP1ProofWithPublicValues): O1jsGroth16;
@@ -0,0 +1,9 @@
1
+ /* @ts-self-types="./pairing_utils.d.ts" */
2
+
3
+ import * as wasm from "./pairing_utils_bg.wasm";
4
+ import { __wbg_set_wasm } from "./pairing_utils_bg.js";
5
+ __wbg_set_wasm(wasm);
6
+ wasm.__wbindgen_start();
7
+ export {
8
+ compute_aux_witness, compute_pairing, convert_snarkjs_groth16_to_o1js, convert_sp1_groth16_to_o1js
9
+ } from "./pairing_utils_bg.js";
@@ -0,0 +1,388 @@
1
+ /**
2
+ * Computes the auxiliary witness from a Miller loop output.
3
+ *
4
+ * # What This Does
5
+ *
6
+ * Takes a 12-element field value (the result of a Miller loop pairing computation)
7
+ * and computes the auxiliary witness needed for efficient verification.
8
+ *
9
+ * The Miller loop is the first step of pairing-based verification. Its output
10
+ * needs further processing (final exponentiation), which is expensive. The
11
+ * auxiliary witness provides precomputed hints that make this step efficient.
12
+ *
13
+ * # Input
14
+ *
15
+ * A JS object matching [`Field12`] structure (12 string fields: g00-g21, h00-h21).
16
+ *
17
+ * # Output
18
+ *
19
+ * A JS object matching [`AuxWitness`] structure containing:
20
+ * - `c`: A 12-element field value
21
+ * - `shift_power`: "0", "1", or "2"
22
+ *
23
+ * # Panics
24
+ *
25
+ * Panics if the input is not a valid Miller loop output (fails internal assertion).
26
+ * @param {Field12} input
27
+ * @returns {AuxWitness}
28
+ */
29
+ export function compute_aux_witness(input) {
30
+ const ret = wasm.compute_aux_witness(input);
31
+ if (ret[2]) {
32
+ throw takeFromExternrefTable0(ret[1]);
33
+ }
34
+ return takeFromExternrefTable0(ret[0]);
35
+ }
36
+
37
+ /**
38
+ * Computes a pairing for a verification key.
39
+ *
40
+ * # What This Does
41
+ *
42
+ * Takes two curve points (alpha and beta from the trusted setup) and computes
43
+ * their pairing using the Miller loop algorithm. The result is a 12-element
44
+ * field value that gets stored in the verification key.
45
+ *
46
+ * This pairing e(alpha, beta) is constant for a given verification key, so it's
47
+ * precomputed once and reused for all proof verifications.
48
+ *
49
+ * # Input
50
+ *
51
+ * A JS object matching [`PairingInput`] structure:
52
+ * - `alpha`: An [`AffinePoint2d`] with `x` and `y` fields
53
+ * - `beta`: A [`ComplexAffinePoint2d`] with `x_c0`, `x_c1`, `y_c0`, `y_c1` fields
54
+ *
55
+ * # Output
56
+ *
57
+ * A JS object matching [`Field12`] structure (12 string fields: g00-g21, h00-h21).
58
+ *
59
+ * # Errors
60
+ *
61
+ * Returns a JS error if input parsing or coordinate conversion fails.
62
+ * @param {PairingInput} input
63
+ * @returns {Field12}
64
+ */
65
+ export function compute_pairing(input) {
66
+ const ret = wasm.compute_pairing(input);
67
+ if (ret[2]) {
68
+ throw takeFromExternrefTable0(ret[1]);
69
+ }
70
+ return takeFromExternrefTable0(ret[0]);
71
+ }
72
+
73
+ /**
74
+ * Converts a snarkjs/circom Groth16 proof and verification key to o1js format.
75
+ *
76
+ * This function takes Groth16 proofs generated by snarkjs (the JavaScript implementation
77
+ * of Groth16 commonly used with circom circuits) and converts them to o1js format for
78
+ * verification in Mina Protocol zkApps.
79
+ *
80
+ * # Conversion Details
81
+ *
82
+ * ## Proof Conversion
83
+ * - The A point (`pi_a`) is **negated** for o1js compatibility. The o1js verification
84
+ * equation uses `-A` rather than `A` in the pairing check.
85
+ * - Points are converted from projective coordinates (with z component) to affine form.
86
+ * - The B point is a G2 point with complex coordinates (x_c0, x_c1, y_c0, y_c1).
87
+ * - The C point is a G1 point with simple coordinates (x, y).
88
+ *
89
+ * ## Verification Key Conversion
90
+ * - All curve points are converted from projective to affine form.
91
+ * - The `alpha_beta` pairing e(α, β) is computed using arkworks `multi_miller_loop`.
92
+ * This is a constant for each VK and is precomputed to save verification time.
93
+ * - A hardcoded `w27` (27th root of unity) is added for pairing optimizations.
94
+ * See https://eprint.iacr.org/2024/640 for the optimization technique.
95
+ * - IC (input commitment) points are mapped to ic0-ic6 fields.
96
+ *
97
+ * ## Validation
98
+ * - The `nPublic` field in the VK must match the number of public inputs provided.
99
+ * - The IC array length must equal nPublic + 1 (ic0 is the constant term).
100
+ *
101
+ * # Input Format
102
+ *
103
+ * - `proof`: snarkjs proof JSON object with:
104
+ * - `pi_a`: `[x, y, z]` - A point in G1 projective coordinates
105
+ * - `pi_b`: `[[x_c0, x_c1], [y_c0, y_c1], [z_c0, z_c1]]` - B point in G2 projective
106
+ * - `pi_c`: `[x, y, z]` - C point in G1 projective coordinates
107
+ *
108
+ * - `public_inputs`: Array of public input strings as decimal numbers, e.g., `["123", "456"]`.
109
+ * Maximum 6 public inputs are supported.
110
+ *
111
+ * - `vk`: snarkjs verification key JSON object with:
112
+ * - `nPublic`: Number of public inputs
113
+ * - `vk_alpha_1`: Alpha point (G1 projective)
114
+ * - `vk_beta_2`: Beta point (G2 projective)
115
+ * - `vk_gamma_2`: Gamma point (G2 projective)
116
+ * - `vk_delta_2`: Delta point (G2 projective)
117
+ * - `IC`: Array of IC points (G1 projective), length = nPublic + 1
118
+ *
119
+ * # Output Format
120
+ *
121
+ * Returns an [`O1jsGroth16`] object containing:
122
+ *
123
+ * - `proof`: o1js-formatted proof with:
124
+ * - `negA`: Negated A point `{x, y}` as decimal strings
125
+ * - `B`: B point `{x_c0, x_c1, y_c0, y_c1}` as decimal strings
126
+ * - `C`: C point `{x, y}` as decimal strings
127
+ * - `pi1` through `pi6`: Public inputs (only present if provided)
128
+ *
129
+ * - `vk`: o1js-formatted verification key with:
130
+ * - `alpha`, `beta`, `gamma`, `delta`: Curve points
131
+ * - `alpha_beta`: Precomputed pairing as 12-element Fq12 field
132
+ * - `w27`: 27th root of unity as 12-element Fq12 field
133
+ * - `ic0` through `ic6`: Input commitment points (only present if in VK)
134
+ *
135
+ * # Errors
136
+ *
137
+ * Returns an error if:
138
+ * - Input JSON parsing fails (invalid structure or types)
139
+ * - VK validation fails (`nPublic` doesn't match public inputs count, wrong IC length)
140
+ * - Point coordinate parsing fails (invalid field element strings)
141
+ * - More than 6 public inputs are provided
142
+ * @param {SnarkjsProof} proof
143
+ * @param {string[]} public_inputs
144
+ * @param {SnarkjsVK} vk
145
+ * @returns {O1jsGroth16}
146
+ */
147
+ export function convert_snarkjs_groth16_to_o1js(proof, public_inputs, vk) {
148
+ const ptr0 = passArrayJsValueToWasm0(public_inputs, wasm.__wbindgen_malloc);
149
+ const len0 = WASM_VECTOR_LEN;
150
+ const ret = wasm.convert_snarkjs_groth16_to_o1js(proof, ptr0, len0, vk);
151
+ if (ret[2]) {
152
+ throw takeFromExternrefTable0(ret[1]);
153
+ }
154
+ return takeFromExternrefTable0(ret[0]);
155
+ }
156
+
157
+ /**
158
+ * Converts an SP1 Groth16 proof to o1js format.
159
+ *
160
+ * This function takes Groth16 proofs generated by SP1 (Succinct's zkVM) and converts
161
+ * them to o1js format for verification in Mina Protocol zkApps. SP1 uses gnark's
162
+ * Groth16 implementation internally, which produces proofs in a compressed format
163
+ * that must be decompressed before conversion.
164
+ *
165
+ * # Conversion Details
166
+ *
167
+ * ## Proof Extraction & Decompression
168
+ * - The `encoded_proof` field contains hex-encoded gnark proof bytes.
169
+ * - The first 4 bytes of the proof are a vkey hash prefix (skipped during parsing).
170
+ * - gnark uses a compressed point format that differs from arkworks. This function
171
+ * decompresses G1 and G2 points using endianness conversion and flag translation.
172
+ * - The decompression follows the gnark → arkworks conversion from sp1-sui.
173
+ *
174
+ * ## Proof Conversion
175
+ * - The A point is **negated** for o1js compatibility. The o1js verification
176
+ * equation uses `-A` rather than `A` in the pairing check.
177
+ * - SP1 Groth16 proofs have exactly 2 public inputs (vkey_hash and public_values_hash).
178
+ *
179
+ * ## Verification Key
180
+ * - All SP1 v5.0.0 Groth16 proofs use the **same verification key**. This VK is
181
+ * embedded in the library (`GROTH16_VK_5_0_0_BYTES`) and loaded automatically.
182
+ * - The VK is decompressed from gnark format to arkworks format.
183
+ * - The `alpha_beta` pairing e(α, β) is computed and included in the output.
184
+ * - The hardcoded `w27` (27th root of unity) is added for pairing optimizations.
185
+ *
186
+ * # Input Format
187
+ *
188
+ * - `sp1_proof`: SP1ProofWithPublicValues JSON shim object representation
189
+ * - FIXME write an example here!
190
+ *
191
+ * # Output Format
192
+ *
193
+ * Returns an [`O1jsGroth16`] object containing:
194
+ *
195
+ * - `proof`: o1js-formatted proof with:
196
+ * - `negA`: Negated A point `{x, y}` as decimal strings
197
+ * - `B`: B point `{x_c0, x_c1, y_c0, y_c1}` as decimal strings
198
+ * - `C`: C point `{x, y}` as decimal strings
199
+ * - `pi1`: First public input (vkey_hash)
200
+ * - `pi2`: Second public input (public_values_hash)
201
+ *
202
+ * - `vk`: o1js-formatted SP1 v5.0.0 verification key with:
203
+ * - `alpha`, `beta`, `gamma`, `delta`: Curve points
204
+ * - `alpha_beta`: Precomputed pairing as 12-element Fq12 field
205
+ * - `w27`: 27th root of unity as 12-element Fq12 field
206
+ * - `ic0`, `ic1`, `ic2`: Input commitment points (SP1 VK has 3 IC points)
207
+ *
208
+ * # Errors
209
+ *
210
+ * Returns an error if:
211
+ * - Input JSON parsing fails (invalid structure or types)
212
+ * - Proof is not the `Groth16` variant (e.g., it's a PLONK proof)
213
+ * - Proof is empty (mock proof - not supported)
214
+ * - Hex decoding of `encoded_proof` fails
215
+ * - gnark point decompression fails (invalid curve points)
216
+ * @param {SP1ProofWithPublicValues} sp1_proof
217
+ * @returns {O1jsGroth16}
218
+ */
219
+ export function convert_sp1_groth16_to_o1js(sp1_proof) {
220
+ const ret = wasm.convert_sp1_groth16_to_o1js(sp1_proof);
221
+ if (ret[2]) {
222
+ throw takeFromExternrefTable0(ret[1]);
223
+ }
224
+ return takeFromExternrefTable0(ret[0]);
225
+ }
226
+ export function __wbg_Error_8c4e43fe74559d73(arg0, arg1) {
227
+ const ret = Error(getStringFromWasm0(arg0, arg1));
228
+ return ret;
229
+ }
230
+ export function __wbg___wbindgen_is_undefined_9e4d92534c42d778(arg0) {
231
+ const ret = arg0 === undefined;
232
+ return ret;
233
+ }
234
+ export function __wbg___wbindgen_string_get_72fb696202c56729(arg0, arg1) {
235
+ const obj = arg1;
236
+ const ret = typeof(obj) === 'string' ? obj : undefined;
237
+ var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
238
+ var len1 = WASM_VECTOR_LEN;
239
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
240
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
241
+ }
242
+ export function __wbg___wbindgen_throw_be289d5034ed271b(arg0, arg1) {
243
+ throw new Error(getStringFromWasm0(arg0, arg1));
244
+ }
245
+ export function __wbg_parse_708461a1feddfb38() { return handleError(function (arg0, arg1) {
246
+ const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
247
+ return ret;
248
+ }, arguments); }
249
+ export function __wbg_stringify_8d1cc6ff383e8bae() { return handleError(function (arg0) {
250
+ const ret = JSON.stringify(arg0);
251
+ return ret;
252
+ }, arguments); }
253
+ export function __wbindgen_init_externref_table() {
254
+ const table = wasm.__wbindgen_externrefs;
255
+ const offset = table.grow(4);
256
+ table.set(0, undefined);
257
+ table.set(offset + 0, undefined);
258
+ table.set(offset + 1, null);
259
+ table.set(offset + 2, true);
260
+ table.set(offset + 3, false);
261
+ }
262
+ function addToExternrefTable0(obj) {
263
+ const idx = wasm.__externref_table_alloc();
264
+ wasm.__wbindgen_externrefs.set(idx, obj);
265
+ return idx;
266
+ }
267
+
268
+ let cachedDataViewMemory0 = null;
269
+ function getDataViewMemory0() {
270
+ if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
271
+ cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
272
+ }
273
+ return cachedDataViewMemory0;
274
+ }
275
+
276
+ function getStringFromWasm0(ptr, len) {
277
+ ptr = ptr >>> 0;
278
+ return decodeText(ptr, len);
279
+ }
280
+
281
+ let cachedUint8ArrayMemory0 = null;
282
+ function getUint8ArrayMemory0() {
283
+ if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
284
+ cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
285
+ }
286
+ return cachedUint8ArrayMemory0;
287
+ }
288
+
289
+ function handleError(f, args) {
290
+ try {
291
+ return f.apply(this, args);
292
+ } catch (e) {
293
+ const idx = addToExternrefTable0(e);
294
+ wasm.__wbindgen_exn_store(idx);
295
+ }
296
+ }
297
+
298
+ function isLikeNone(x) {
299
+ return x === undefined || x === null;
300
+ }
301
+
302
+ function passArrayJsValueToWasm0(array, malloc) {
303
+ const ptr = malloc(array.length * 4, 4) >>> 0;
304
+ for (let i = 0; i < array.length; i++) {
305
+ const add = addToExternrefTable0(array[i]);
306
+ getDataViewMemory0().setUint32(ptr + 4 * i, add, true);
307
+ }
308
+ WASM_VECTOR_LEN = array.length;
309
+ return ptr;
310
+ }
311
+
312
+ function passStringToWasm0(arg, malloc, realloc) {
313
+ if (realloc === undefined) {
314
+ const buf = cachedTextEncoder.encode(arg);
315
+ const ptr = malloc(buf.length, 1) >>> 0;
316
+ getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
317
+ WASM_VECTOR_LEN = buf.length;
318
+ return ptr;
319
+ }
320
+
321
+ let len = arg.length;
322
+ let ptr = malloc(len, 1) >>> 0;
323
+
324
+ const mem = getUint8ArrayMemory0();
325
+
326
+ let offset = 0;
327
+
328
+ for (; offset < len; offset++) {
329
+ const code = arg.charCodeAt(offset);
330
+ if (code > 0x7F) break;
331
+ mem[ptr + offset] = code;
332
+ }
333
+ if (offset !== len) {
334
+ if (offset !== 0) {
335
+ arg = arg.slice(offset);
336
+ }
337
+ ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
338
+ const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
339
+ const ret = cachedTextEncoder.encodeInto(arg, view);
340
+
341
+ offset += ret.written;
342
+ ptr = realloc(ptr, len, offset, 1) >>> 0;
343
+ }
344
+
345
+ WASM_VECTOR_LEN = offset;
346
+ return ptr;
347
+ }
348
+
349
+ function takeFromExternrefTable0(idx) {
350
+ const value = wasm.__wbindgen_externrefs.get(idx);
351
+ wasm.__externref_table_dealloc(idx);
352
+ return value;
353
+ }
354
+
355
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
356
+ cachedTextDecoder.decode();
357
+ const MAX_SAFARI_DECODE_BYTES = 2146435072;
358
+ let numBytesDecoded = 0;
359
+ function decodeText(ptr, len) {
360
+ numBytesDecoded += len;
361
+ if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
362
+ cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
363
+ cachedTextDecoder.decode();
364
+ numBytesDecoded = len;
365
+ }
366
+ return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
367
+ }
368
+
369
+ const cachedTextEncoder = new TextEncoder();
370
+
371
+ if (!('encodeInto' in cachedTextEncoder)) {
372
+ cachedTextEncoder.encodeInto = function (arg, view) {
373
+ const buf = cachedTextEncoder.encode(arg);
374
+ view.set(buf);
375
+ return {
376
+ read: arg.length,
377
+ written: buf.length
378
+ };
379
+ };
380
+ }
381
+
382
+ let WASM_VECTOR_LEN = 0;
383
+
384
+
385
+ let wasm;
386
+ export function __wbg_set_wasm(val) {
387
+ wasm = val;
388
+ }
Binary file