@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 +441 -0
- package/package.json +23 -0
- package/pairing_utils.d.ts +466 -0
- package/pairing_utils.js +9 -0
- package/pairing_utils_bg.js +388 -0
- package/pairing_utils_bg.wasm +0 -0
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;
|
package/pairing_utils.js
ADDED
|
@@ -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
|