@nori-zk/proof-conversion-utils 0.5.0 → 0.5.2
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 +181 -42
- package/package.json +1 -1
- package/pairing_utils.d.ts +2 -2
- package/pairing_utils_bg.js +2 -2
- package/pairing_utils_bg.wasm +0 -0
package/README.md
CHANGED
|
@@ -14,6 +14,8 @@ This package provides utilities to assist witness creation and alpha-beta pairin
|
|
|
14
14
|
|
|
15
15
|
## TypeScript API
|
|
16
16
|
|
|
17
|
+
--------------------------------------------------------------------------------------------
|
|
18
|
+
|
|
17
19
|
### Types
|
|
18
20
|
|
|
19
21
|
#### `AffinePoint2d`
|
|
@@ -244,7 +246,6 @@ interface SnarkjsVK {
|
|
|
244
246
|
vk_beta_2: [[string, string], [string, string], [string, string]];
|
|
245
247
|
vk_gamma_2: [[string, string], [string, string], [string, string]];
|
|
246
248
|
vk_delta_2: [[string, string], [string, string], [string, string]];
|
|
247
|
-
vk_alphabeta_12: [[string, string], [string, string], [string, string]];
|
|
248
249
|
IC: Array<[string, string, string]>;
|
|
249
250
|
}
|
|
250
251
|
```
|
|
@@ -305,74 +306,212 @@ export interface SP1ProofWithPublicValues {
|
|
|
305
306
|
}
|
|
306
307
|
```
|
|
307
308
|
|
|
309
|
+
--------------------------------------------------------------------------------------------
|
|
310
|
+
|
|
308
311
|
### Functions
|
|
309
312
|
|
|
310
|
-
#### `
|
|
313
|
+
#### `compute_aux_witness`
|
|
311
314
|
|
|
312
|
-
|
|
315
|
+
```typescript
|
|
316
|
+
export function compute_aux_witness(input: Field12): AuxWitness;
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Computes the auxiliary witness from a Miller loop output.
|
|
320
|
+
|
|
321
|
+
**What This Does**
|
|
322
|
+
|
|
323
|
+
Takes a 12-element field value (the result of a Miller loop pairing computation)
|
|
324
|
+
and computes the auxiliary witness needed for efficient verification.
|
|
325
|
+
|
|
326
|
+
The Miller loop is the first step of pairing-based verification. Its output
|
|
327
|
+
needs further processing (final exponentiation), which is expensive. The
|
|
328
|
+
auxiliary witness provides precomputed hints that make this step efficient.
|
|
329
|
+
|
|
330
|
+
**Input**
|
|
331
|
+
|
|
332
|
+
A JS object matching `Field12` structure (12 string fields: g00-g21, h00-h21).
|
|
313
333
|
|
|
314
|
-
|
|
334
|
+
**Output**
|
|
335
|
+
|
|
336
|
+
Return a JS object matching `AuxWitness` structure containing:
|
|
337
|
+
- `c`: A 12-element field value
|
|
338
|
+
- `shift_power`: "0", "1", or "2"
|
|
339
|
+
|
|
340
|
+
**Error**
|
|
341
|
+
|
|
342
|
+
Throws a JsError if the input is not a valid Miller loop output (fails internal assertion).
|
|
343
|
+
|
|
344
|
+
#### `compute_pairing`
|
|
315
345
|
|
|
316
346
|
```typescript
|
|
317
|
-
|
|
318
|
-
alpha: { x: '...', y: '...' },
|
|
319
|
-
beta: { x_c0: '...', x_c1: '...', y_c0: '...', y_c1: '...' }
|
|
320
|
-
});
|
|
347
|
+
export function compute_pairing(input: PairingInput): Field12;
|
|
321
348
|
```
|
|
322
349
|
|
|
323
|
-
|
|
350
|
+
Computes a pairing for a verification key.
|
|
324
351
|
|
|
325
|
-
|
|
352
|
+
**What This Does**
|
|
353
|
+
|
|
354
|
+
Takes two curve points (alpha and beta from the trusted setup) and computes
|
|
355
|
+
their pairing using the Miller loop algorithm. The result is a 12-element
|
|
356
|
+
field value that gets stored in the verification key.
|
|
357
|
+
|
|
358
|
+
This pairing e(alpha, beta) is constant for a given verification key, so it's
|
|
359
|
+
precomputed once and reused for all proof verifications.
|
|
360
|
+
|
|
361
|
+
**Input**
|
|
362
|
+
|
|
363
|
+
A JS object matching `PairingInput` structure:
|
|
364
|
+
- `alpha`: An `AffinePoint2d` with `x` and `y` fields
|
|
365
|
+
- `beta`: A `ComplexAffinePoint2d` with `x_c0`, `x_c1`, `y_c0`, `y_c1` fields
|
|
326
366
|
|
|
327
|
-
|
|
367
|
+
**Output**
|
|
368
|
+
|
|
369
|
+
Returns a JS object matching `Field12` structure (12 string fields: g00-g21, h00-h21).
|
|
370
|
+
|
|
371
|
+
**Errors**
|
|
372
|
+
|
|
373
|
+
Throws a JS error if input parsing or coordinate conversion fails.
|
|
374
|
+
|
|
375
|
+
#### `convert_snarkjs_groth16_to_o1js`
|
|
328
376
|
|
|
329
377
|
```typescript
|
|
330
|
-
|
|
331
|
-
g00: '...', g01: '...', g10: '...', g11: '...', g20: '...', g21: '...',
|
|
332
|
-
h00: '...', h01: '...', h10: '...', h11: '...', h20: '...', h21: '...'
|
|
333
|
-
});
|
|
378
|
+
export function convert_snarkjs_groth16_to_o1js(proof: SnarkjsProof, public_inputs: string[], vk: SnarkjsVK): O1jsGroth16;
|
|
334
379
|
```
|
|
335
380
|
|
|
336
|
-
|
|
381
|
+
Converts a snarkjs/circom Groth16 proof and verification key to o1js format.
|
|
337
382
|
|
|
338
|
-
|
|
383
|
+
This function takes Groth16 proofs generated by snarkjs (the JavaScript implementation
|
|
384
|
+
of Groth16 commonly used with circom circuits) and converts them to o1js format for
|
|
385
|
+
verification in Mina Protocol zkApps.
|
|
339
386
|
|
|
340
|
-
|
|
387
|
+
**Conversion Details**
|
|
341
388
|
|
|
342
|
-
**
|
|
343
|
-
- The A point (`pi_a`) is negated for o1js compatibility
|
|
344
|
-
|
|
345
|
-
-
|
|
346
|
-
-
|
|
389
|
+
**Proof Conversion**
|
|
390
|
+
- The A point (`pi_a`) is **negated** for o1js compatibility. The o1js verification
|
|
391
|
+
equation uses `-A` rather than `A` in the pairing check.
|
|
392
|
+
- Points are converted from projective coordinates (with z component) to affine form.
|
|
393
|
+
- The B point is a G2 point with complex coordinates (x_c0, x_c1, y_c0, y_c1).
|
|
394
|
+
- The C point is a G1 point with simple coordinates (x, y).
|
|
347
395
|
|
|
348
|
-
|
|
349
|
-
|
|
396
|
+
**Verification Key Conversion**
|
|
397
|
+
- All curve points are converted from projective to affine form.
|
|
398
|
+
- The `alpha_beta` pairing e(α, β) is computed using arkworks `multi_miller_loop`.
|
|
399
|
+
This is a constant for each VK and is precomputed to save verification time.
|
|
400
|
+
- A hardcoded `w27` (27th root of unity) is added for pairing optimizations.
|
|
401
|
+
See https://eprint.iacr.org/2024/640 for the optimization technique.
|
|
402
|
+
- IC (input commitment) points are mapped to ic0-ic6 fields.
|
|
350
403
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
snarkjsVK
|
|
355
|
-
);
|
|
356
|
-
```
|
|
404
|
+
**Validation**
|
|
405
|
+
- The `nPublic` field in the VK must match the number of public inputs provided.
|
|
406
|
+
- The IC array length must equal nPublic + 1 (ic0 is the constant term).
|
|
357
407
|
|
|
358
|
-
|
|
408
|
+
**Input Format**
|
|
359
409
|
|
|
360
|
-
|
|
410
|
+
- `proof`: snarkjs proof JSON object with:
|
|
411
|
+
- `pi_a`: `[x, y, z]` - A point in G1 projective coordinates
|
|
412
|
+
- `pi_b`: `[[x_c0, x_c1], [y_c0, y_c1], [z_c0, z_c1]]` - B point in G2 projective
|
|
413
|
+
- `pi_c`: `[x, y, z]` - C point in G1 projective coordinates
|
|
361
414
|
|
|
362
|
-
|
|
415
|
+
- `public_inputs`: Array of public input strings as decimal numbers, e.g., `["123", "456"]`.
|
|
416
|
+
Maximum 6 public inputs are supported.
|
|
363
417
|
|
|
364
|
-
|
|
365
|
-
-
|
|
366
|
-
-
|
|
367
|
-
-
|
|
368
|
-
-
|
|
418
|
+
- `vk`: snarkjs verification key JSON object with:
|
|
419
|
+
- `nPublic`: Number of public inputs
|
|
420
|
+
- `vk_alpha_1`: Alpha point (G1 projective)
|
|
421
|
+
- `vk_beta_2`: Beta point (G2 projective)
|
|
422
|
+
- `vk_gamma_2`: Gamma point (G2 projective)
|
|
423
|
+
- `vk_delta_2`: Delta point (G2 projective)
|
|
424
|
+
- `IC`: Array of IC points (G1 projective), length = nPublic + 1
|
|
369
425
|
|
|
370
|
-
|
|
371
|
-
|
|
426
|
+
**Output Format**
|
|
427
|
+
|
|
428
|
+
Returns a JS object matching `O1jsGroth16` containing:
|
|
429
|
+
|
|
430
|
+
- `proof`: o1js-formatted proof with:
|
|
431
|
+
- `negA`: Negated A point `{x, y}` as decimal strings
|
|
432
|
+
- `B`: B point `{x_c0, x_c1, y_c0, y_c1}` as decimal strings
|
|
433
|
+
- `C`: C point `{x, y}` as decimal strings
|
|
434
|
+
- `pi1` through `pi6`: Public inputs (only present if provided)
|
|
435
|
+
|
|
436
|
+
- `vk`: o1js-formatted verification key with:
|
|
437
|
+
- `alpha`, `beta`, `gamma`, `delta`: Curve points
|
|
438
|
+
- `alpha_beta`: Precomputed pairing as 12-element Fq12 field
|
|
439
|
+
- `w27`: 27th root of unity as 12-element Fq12 field
|
|
440
|
+
- `ic0` through `ic6`: Input commitment points (only present if in VK)
|
|
441
|
+
|
|
442
|
+
**Errors**
|
|
372
443
|
|
|
373
|
-
|
|
444
|
+
Throws a JsError error if:
|
|
445
|
+
- Input JSON parsing fails (invalid structure or types)
|
|
446
|
+
- VK validation fails (`nPublic` doesn't match public inputs count, wrong IC length)
|
|
447
|
+
- Point coordinate parsing fails (invalid field element strings)
|
|
448
|
+
- More than 6 public inputs are provided
|
|
449
|
+
|
|
450
|
+
#### `convert_sp1_groth16_to_o1js`
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
export function convert_sp1_groth16_to_o1js(sp1_proof: SP1ProofWithPublicValues): O1jsGroth16;
|
|
374
454
|
```
|
|
375
455
|
|
|
456
|
+
Converts an SP1 Groth16 proof to o1js format.
|
|
457
|
+
|
|
458
|
+
This function takes Groth16 proofs generated by SP1 (Succinct's zkVM) and converts
|
|
459
|
+
them to o1js format for verification in Mina Protocol zkApps. SP1 uses gnark's
|
|
460
|
+
Groth16 implementation internally, which produces proofs in a compressed format
|
|
461
|
+
that must be decompressed before conversion.
|
|
462
|
+
|
|
463
|
+
**Conversion Details**
|
|
464
|
+
|
|
465
|
+
**Proof Extraction & Decompression**
|
|
466
|
+
- The `encoded_proof` field contains hex-encoded gnark proof bytes.
|
|
467
|
+
- The first 4 bytes of the proof are a vkey hash prefix (skipped during parsing).
|
|
468
|
+
- gnark uses a compressed point format that differs from arkworks. This function
|
|
469
|
+
decompresses G1 and G2 points using endianness conversion and flag translation.
|
|
470
|
+
- The decompression follows the gnark → arkworks conversion from sp1-sui.
|
|
471
|
+
|
|
472
|
+
**Proof Conversion**
|
|
473
|
+
- The A point is **negated** for o1js compatibility. The o1js verification
|
|
474
|
+
equation uses `-A` rather than `A` in the pairing check.
|
|
475
|
+
- SP1 Groth16 proofs have exactly 2 public inputs (vkey_hash and public_values_hash).
|
|
476
|
+
|
|
477
|
+
**Verification Key**
|
|
478
|
+
- All SP1 v5.0.0 Groth16 proofs use the **same verification key**. This VK is
|
|
479
|
+
embedded in the library (`GROTH16_VK_5_0_0_BYTES`) and loaded automatically.
|
|
480
|
+
- The VK is decompressed from gnark format to arkworks format.
|
|
481
|
+
- The `alpha_beta` pairing e(α, β) is computed and included in the output.
|
|
482
|
+
- The hardcoded `w27` (27th root of unity) is added for pairing optimizations.
|
|
483
|
+
|
|
484
|
+
**Input Format**
|
|
485
|
+
|
|
486
|
+
- `sp1_proof`: SP1ProofWithPublicValues JSON shim object representation
|
|
487
|
+
- FIXME write an example here!
|
|
488
|
+
|
|
489
|
+
**Output Format**
|
|
490
|
+
|
|
491
|
+
Returns a JS object `O1jsGroth16` containing:
|
|
492
|
+
|
|
493
|
+
- `proof`: o1js-formatted proof with:
|
|
494
|
+
- `negA`: Negated A point `{x, y}` as decimal strings
|
|
495
|
+
- `B`: B point `{x_c0, x_c1, y_c0, y_c1}` as decimal strings
|
|
496
|
+
- `C`: C point `{x, y}` as decimal strings
|
|
497
|
+
- `pi1`: First public input (vkey_hash)
|
|
498
|
+
- `pi2`: Second public input (public_values_hash)
|
|
499
|
+
|
|
500
|
+
- `vk`: o1js-formatted SP1 v5.0.0 verification key with:
|
|
501
|
+
- `alpha`, `beta`, `gamma`, `delta`: Curve points
|
|
502
|
+
- `alpha_beta`: Precomputed pairing as 12-element Fq12 field
|
|
503
|
+
- `w27`: 27th root of unity as 12-element Fq12 field
|
|
504
|
+
- `ic0`, `ic1`, `ic2`: Input commitment points (SP1 VK has 3 IC points)
|
|
505
|
+
|
|
506
|
+
**Errors**
|
|
507
|
+
|
|
508
|
+
Throws a JsError error if:
|
|
509
|
+
- Input JSON parsing fails (invalid structure or types)
|
|
510
|
+
- Proof is not the `Groth16` variant (e.g., it's a PLONK proof)
|
|
511
|
+
- Proof is empty (mock proof - not supported)
|
|
512
|
+
- Hex decoding of `encoded_proof` fails
|
|
513
|
+
- gnark point decompression fails (invalid curve points)
|
|
514
|
+
|
|
376
515
|
## Usage Examples
|
|
377
516
|
|
|
378
517
|
### Converting SnarkJS Proof
|
package/package.json
CHANGED
package/pairing_utils.d.ts
CHANGED
|
@@ -297,9 +297,9 @@ export interface SP1PublicValues {
|
|
|
297
297
|
* - `c`: A 12-element field value
|
|
298
298
|
* - `shift_power`: "0", "1", or "2"
|
|
299
299
|
*
|
|
300
|
-
* #
|
|
300
|
+
* # Error
|
|
301
301
|
*
|
|
302
|
-
*
|
|
302
|
+
* Returns a JsError if the input is not a valid Miller loop output (fails internal assertion).
|
|
303
303
|
*/
|
|
304
304
|
export function compute_aux_witness(input: Field12): AuxWitness;
|
|
305
305
|
|
package/pairing_utils_bg.js
CHANGED
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
* - `c`: A 12-element field value
|
|
21
21
|
* - `shift_power`: "0", "1", or "2"
|
|
22
22
|
*
|
|
23
|
-
* #
|
|
23
|
+
* # Error
|
|
24
24
|
*
|
|
25
|
-
*
|
|
25
|
+
* Returns a JsError if the input is not a valid Miller loop output (fails internal assertion).
|
|
26
26
|
* @param {Field12} input
|
|
27
27
|
* @returns {AuxWitness}
|
|
28
28
|
*/
|
package/pairing_utils_bg.wasm
CHANGED
|
Binary file
|