@izi-noir/sdk 0.1.9 → 0.1.11
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/dist/{IProvingSystem-D0X9Rp3W.d.ts → IProvingSystem-BKgFRl27.d.ts} +97 -2
- package/dist/{IProvingSystem-BpI0rmve.d.cts → IProvingSystem-SfzgcbqH.d.cts} +97 -2
- package/dist/index.cjs +447 -44
- package/dist/index.d.cts +111 -85
- package/dist/index.d.ts +111 -85
- package/dist/index.js +446 -44
- package/dist/providers/arkworks.cjs +444 -44
- package/dist/providers/arkworks.d.cts +7 -4
- package/dist/providers/arkworks.d.ts +7 -4
- package/dist/providers/arkworks.js +444 -44
- package/dist/providers/barretenberg.cjs +444 -44
- package/dist/providers/barretenberg.d.cts +4 -4
- package/dist/providers/barretenberg.d.ts +4 -4
- package/dist/providers/barretenberg.js +444 -44
- package/dist/providers/sunspot.d.cts +2 -2
- package/dist/providers/sunspot.d.ts +2 -2
- package/dist/{wasmInit-oOZwkgo_.d.ts → wasmInit-D3RyRKIC.d.ts} +7 -3
- package/dist/{wasmInit-D615cpte.d.cts → wasmInit-Wyynuk6r.d.cts} +7 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -67,7 +67,9 @@ var init_Barretenberg = __esm({
|
|
|
67
67
|
import_noir_js = require("@noir-lang/noir_js");
|
|
68
68
|
import_bb = require("@aztec/bb.js");
|
|
69
69
|
Barretenberg = class {
|
|
70
|
-
|
|
70
|
+
// Note: options parameter is accepted but not used - Barretenberg uses Noir's ACIR directly
|
|
71
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
72
|
+
async compile(noirCode, _options) {
|
|
71
73
|
const { basePath, cleanup } = await createTempDir();
|
|
72
74
|
const fm = (0, import_noir_wasm.createFileManager)(basePath);
|
|
73
75
|
const nargoToml = `[package]
|
|
@@ -125,6 +127,377 @@ authors = [""]
|
|
|
125
127
|
}
|
|
126
128
|
});
|
|
127
129
|
|
|
130
|
+
// src/infra/provingSystems/R1csBuilder.ts
|
|
131
|
+
var R1csBuilder;
|
|
132
|
+
var init_R1csBuilder = __esm({
|
|
133
|
+
"src/infra/provingSystems/R1csBuilder.ts"() {
|
|
134
|
+
"use strict";
|
|
135
|
+
R1csBuilder = class {
|
|
136
|
+
constructor(parsedCircuit) {
|
|
137
|
+
this.parsedCircuit = parsedCircuit;
|
|
138
|
+
}
|
|
139
|
+
constraints = [];
|
|
140
|
+
witnessMap = /* @__PURE__ */ new Map();
|
|
141
|
+
nextWitnessIdx = 1;
|
|
142
|
+
// w_0 = 1 is reserved
|
|
143
|
+
publicIndices = [];
|
|
144
|
+
privateIndices = [];
|
|
145
|
+
// BN254 scalar field modulus - 1 (for representing -1)
|
|
146
|
+
// Fr modulus = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
|
147
|
+
// -1 mod Fr = Fr - 1
|
|
148
|
+
NEG_ONE = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000";
|
|
149
|
+
/**
|
|
150
|
+
* Build R1CS definition from the parsed circuit
|
|
151
|
+
*/
|
|
152
|
+
build() {
|
|
153
|
+
this.registerInputs();
|
|
154
|
+
for (const stmt of this.parsedCircuit.statements) {
|
|
155
|
+
this.processStatement(stmt);
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
num_witnesses: this.nextWitnessIdx,
|
|
159
|
+
public_inputs: this.publicIndices,
|
|
160
|
+
private_inputs: this.privateIndices,
|
|
161
|
+
constraints: this.constraints
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get the witness index for an input parameter name
|
|
166
|
+
*/
|
|
167
|
+
getWitnessIndex(name) {
|
|
168
|
+
return this.witnessMap.get(name);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Register all circuit inputs as witnesses
|
|
172
|
+
* Public inputs come first, then private inputs
|
|
173
|
+
*/
|
|
174
|
+
registerInputs() {
|
|
175
|
+
for (const param of this.parsedCircuit.publicParams) {
|
|
176
|
+
const idx = this.nextWitnessIdx++;
|
|
177
|
+
this.witnessMap.set(param.name, idx);
|
|
178
|
+
this.publicIndices.push(idx);
|
|
179
|
+
}
|
|
180
|
+
for (const param of this.parsedCircuit.privateParams) {
|
|
181
|
+
const idx = this.nextWitnessIdx++;
|
|
182
|
+
this.witnessMap.set(param.name, idx);
|
|
183
|
+
this.privateIndices.push(idx);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Process a single statement and generate constraints
|
|
188
|
+
*/
|
|
189
|
+
processStatement(stmt) {
|
|
190
|
+
switch (stmt.kind) {
|
|
191
|
+
case "assert":
|
|
192
|
+
this.processAssert(stmt.condition);
|
|
193
|
+
break;
|
|
194
|
+
case "variable_declaration":
|
|
195
|
+
this.processVariableDecl(stmt.name, stmt.initializer);
|
|
196
|
+
break;
|
|
197
|
+
case "assignment":
|
|
198
|
+
this.processAssignment(stmt.target, stmt.value);
|
|
199
|
+
break;
|
|
200
|
+
case "if_statement":
|
|
201
|
+
for (const s of stmt.consequent) {
|
|
202
|
+
this.processStatement(s);
|
|
203
|
+
}
|
|
204
|
+
if (stmt.alternate) {
|
|
205
|
+
for (const s of stmt.alternate) {
|
|
206
|
+
this.processStatement(s);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
break;
|
|
210
|
+
case "for_statement":
|
|
211
|
+
throw new Error(
|
|
212
|
+
"For loops are not yet supported in R1CS generation. Use the Barretenberg backend for complex circuits."
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Process an assert statement
|
|
218
|
+
* The condition must evaluate to true for a valid proof
|
|
219
|
+
*/
|
|
220
|
+
processAssert(condition) {
|
|
221
|
+
if (condition.kind === "binary") {
|
|
222
|
+
this.processBinaryAssert(condition);
|
|
223
|
+
} else if (condition.kind === "identifier") {
|
|
224
|
+
const idx = this.getOrCreateWitness(condition);
|
|
225
|
+
this.constraints.push({
|
|
226
|
+
a: [["0x1", idx]],
|
|
227
|
+
b: [["0x1", 0]],
|
|
228
|
+
// * 1
|
|
229
|
+
c: [["0x1", 0]]
|
|
230
|
+
// = 1 (w_0)
|
|
231
|
+
});
|
|
232
|
+
} else {
|
|
233
|
+
throw new Error(`Unsupported assert condition kind: ${condition.kind}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Process a binary expression in an assert
|
|
238
|
+
*/
|
|
239
|
+
processBinaryAssert(expr) {
|
|
240
|
+
const { left, operator, right } = expr;
|
|
241
|
+
switch (operator) {
|
|
242
|
+
case "==":
|
|
243
|
+
this.processEquality(left, right);
|
|
244
|
+
break;
|
|
245
|
+
case "!=":
|
|
246
|
+
throw new Error(
|
|
247
|
+
"Inequality (!=) is not yet supported in R1CS. Use equality (==) instead."
|
|
248
|
+
);
|
|
249
|
+
case "+":
|
|
250
|
+
case "-":
|
|
251
|
+
case "*":
|
|
252
|
+
case "/":
|
|
253
|
+
case "%":
|
|
254
|
+
throw new Error(
|
|
255
|
+
`Arithmetic operator ${operator} must be part of an equality assertion. Use: assert(a ${operator} b == c)`
|
|
256
|
+
);
|
|
257
|
+
case "<":
|
|
258
|
+
case ">":
|
|
259
|
+
case "<=":
|
|
260
|
+
case ">=":
|
|
261
|
+
throw new Error(
|
|
262
|
+
`Comparison operators (${operator}) require range proofs which are not yet supported. Use the Barretenberg backend for comparison operations.`
|
|
263
|
+
);
|
|
264
|
+
case "&":
|
|
265
|
+
case "|":
|
|
266
|
+
throw new Error(
|
|
267
|
+
`Logical operator ${operator} is not yet supported in R1CS.`
|
|
268
|
+
);
|
|
269
|
+
default:
|
|
270
|
+
throw new Error(`Unsupported operator in assert: ${operator}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Process an equality assertion: assert(left == right)
|
|
275
|
+
*/
|
|
276
|
+
processEquality(left, right) {
|
|
277
|
+
if (left.kind === "binary" && left.operator === "*") {
|
|
278
|
+
this.processMultiplicationEquality(left.left, left.right, right);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
if (right.kind === "binary" && right.operator === "*") {
|
|
282
|
+
this.processMultiplicationEquality(right.left, right.right, left);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
if (left.kind === "binary" && left.operator === "+") {
|
|
286
|
+
this.processAdditionEquality(left.left, left.right, right);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (right.kind === "binary" && right.operator === "+") {
|
|
290
|
+
this.processAdditionEquality(right.left, right.right, left);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
if (left.kind === "binary" && left.operator === "-") {
|
|
294
|
+
this.processSubtractionEquality(left.left, left.right, right);
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
if (right.kind === "binary" && right.operator === "-") {
|
|
298
|
+
this.processSubtractionEquality(right.left, right.right, left);
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
const leftIdx = this.getOrCreateWitness(left);
|
|
302
|
+
const rightIdx = this.getOrCreateWitness(right);
|
|
303
|
+
this.constraints.push({
|
|
304
|
+
a: [
|
|
305
|
+
["0x1", leftIdx],
|
|
306
|
+
[this.NEG_ONE, rightIdx]
|
|
307
|
+
],
|
|
308
|
+
// a - b
|
|
309
|
+
b: [["0x1", 0]],
|
|
310
|
+
// * 1 (w_0 = 1)
|
|
311
|
+
c: []
|
|
312
|
+
// = 0
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Process multiplication equality: assert(a * b == c)
|
|
317
|
+
* R1CS: a * b = c
|
|
318
|
+
*/
|
|
319
|
+
processMultiplicationEquality(left, right, result) {
|
|
320
|
+
const leftIdx = this.getOrCreateWitness(left);
|
|
321
|
+
const rightIdx = this.getOrCreateWitness(right);
|
|
322
|
+
const resultIdx = this.getOrCreateWitness(result);
|
|
323
|
+
this.constraints.push({
|
|
324
|
+
a: [["0x1", leftIdx]],
|
|
325
|
+
b: [["0x1", rightIdx]],
|
|
326
|
+
c: [["0x1", resultIdx]]
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Process addition equality: assert(a + b == c)
|
|
331
|
+
* R1CS: (a + b - c) * 1 = 0
|
|
332
|
+
* Which is: (a + b) * 1 = c
|
|
333
|
+
*/
|
|
334
|
+
processAdditionEquality(left, right, result) {
|
|
335
|
+
const leftIdx = this.getOrCreateWitness(left);
|
|
336
|
+
const rightIdx = this.getOrCreateWitness(right);
|
|
337
|
+
const resultIdx = this.getOrCreateWitness(result);
|
|
338
|
+
this.constraints.push({
|
|
339
|
+
a: [
|
|
340
|
+
["0x1", leftIdx],
|
|
341
|
+
["0x1", rightIdx]
|
|
342
|
+
],
|
|
343
|
+
// a + b
|
|
344
|
+
b: [["0x1", 0]],
|
|
345
|
+
// * 1
|
|
346
|
+
c: [["0x1", resultIdx]]
|
|
347
|
+
// = c
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Process subtraction equality: assert(a - b == c)
|
|
352
|
+
* R1CS: (a - b) * 1 = c
|
|
353
|
+
*/
|
|
354
|
+
processSubtractionEquality(left, right, result) {
|
|
355
|
+
const leftIdx = this.getOrCreateWitness(left);
|
|
356
|
+
const rightIdx = this.getOrCreateWitness(right);
|
|
357
|
+
const resultIdx = this.getOrCreateWitness(result);
|
|
358
|
+
this.constraints.push({
|
|
359
|
+
a: [
|
|
360
|
+
["0x1", leftIdx],
|
|
361
|
+
[this.NEG_ONE, rightIdx]
|
|
362
|
+
],
|
|
363
|
+
// a - b
|
|
364
|
+
b: [["0x1", 0]],
|
|
365
|
+
// * 1
|
|
366
|
+
c: [["0x1", resultIdx]]
|
|
367
|
+
// = c
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Process a variable declaration: let x = expr
|
|
372
|
+
* Creates a new witness for x and adds constraint if needed
|
|
373
|
+
*/
|
|
374
|
+
processVariableDecl(name, initializer) {
|
|
375
|
+
const varIdx = this.nextWitnessIdx++;
|
|
376
|
+
this.witnessMap.set(name, varIdx);
|
|
377
|
+
if (initializer.kind === "identifier") {
|
|
378
|
+
const initIdx = this.getOrCreateWitness(initializer);
|
|
379
|
+
this.constraints.push({
|
|
380
|
+
a: [
|
|
381
|
+
["0x1", varIdx],
|
|
382
|
+
[this.NEG_ONE, initIdx]
|
|
383
|
+
],
|
|
384
|
+
b: [["0x1", 0]],
|
|
385
|
+
c: []
|
|
386
|
+
});
|
|
387
|
+
} else if (initializer.kind === "literal") {
|
|
388
|
+
} else if (initializer.kind === "binary") {
|
|
389
|
+
this.processVariableInitBinary(varIdx, initializer);
|
|
390
|
+
} else {
|
|
391
|
+
throw new Error(
|
|
392
|
+
`Unsupported initializer kind for variable declaration: ${initializer.kind}`
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Process a binary expression as variable initializer
|
|
398
|
+
*/
|
|
399
|
+
processVariableInitBinary(varIdx, expr) {
|
|
400
|
+
const { left, operator, right } = expr;
|
|
401
|
+
const leftIdx = this.getOrCreateWitness(left);
|
|
402
|
+
const rightIdx = this.getOrCreateWitness(right);
|
|
403
|
+
switch (operator) {
|
|
404
|
+
case "*":
|
|
405
|
+
this.constraints.push({
|
|
406
|
+
a: [["0x1", leftIdx]],
|
|
407
|
+
b: [["0x1", rightIdx]],
|
|
408
|
+
c: [["0x1", varIdx]]
|
|
409
|
+
});
|
|
410
|
+
break;
|
|
411
|
+
case "+":
|
|
412
|
+
this.constraints.push({
|
|
413
|
+
a: [
|
|
414
|
+
["0x1", leftIdx],
|
|
415
|
+
["0x1", rightIdx]
|
|
416
|
+
],
|
|
417
|
+
b: [["0x1", 0]],
|
|
418
|
+
c: [["0x1", varIdx]]
|
|
419
|
+
});
|
|
420
|
+
break;
|
|
421
|
+
case "-":
|
|
422
|
+
this.constraints.push({
|
|
423
|
+
a: [
|
|
424
|
+
["0x1", leftIdx],
|
|
425
|
+
[this.NEG_ONE, rightIdx]
|
|
426
|
+
],
|
|
427
|
+
b: [["0x1", 0]],
|
|
428
|
+
c: [["0x1", varIdx]]
|
|
429
|
+
});
|
|
430
|
+
break;
|
|
431
|
+
default:
|
|
432
|
+
throw new Error(
|
|
433
|
+
`Unsupported operator in variable initializer: ${operator}`
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Process an assignment: x = expr
|
|
439
|
+
* Updates the witness mapping
|
|
440
|
+
*/
|
|
441
|
+
processAssignment(target, value) {
|
|
442
|
+
const existingIdx = this.witnessMap.get(target);
|
|
443
|
+
if (existingIdx === void 0) {
|
|
444
|
+
throw new Error(`Assignment to undeclared variable: ${target}`);
|
|
445
|
+
}
|
|
446
|
+
if (value.kind === "identifier") {
|
|
447
|
+
const valueIdx = this.getOrCreateWitness(value);
|
|
448
|
+
this.constraints.push({
|
|
449
|
+
a: [
|
|
450
|
+
["0x1", existingIdx],
|
|
451
|
+
[this.NEG_ONE, valueIdx]
|
|
452
|
+
],
|
|
453
|
+
b: [["0x1", 0]],
|
|
454
|
+
c: []
|
|
455
|
+
});
|
|
456
|
+
} else if (value.kind === "binary") {
|
|
457
|
+
this.processVariableInitBinary(existingIdx, value);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Get or create a witness index for an expression
|
|
462
|
+
*/
|
|
463
|
+
getOrCreateWitness(expr) {
|
|
464
|
+
if (expr.kind === "identifier") {
|
|
465
|
+
const existing = this.witnessMap.get(expr.name);
|
|
466
|
+
if (existing !== void 0) {
|
|
467
|
+
return existing;
|
|
468
|
+
}
|
|
469
|
+
const idx = this.nextWitnessIdx++;
|
|
470
|
+
this.witnessMap.set(expr.name, idx);
|
|
471
|
+
return idx;
|
|
472
|
+
}
|
|
473
|
+
if (expr.kind === "literal") {
|
|
474
|
+
const idx = this.nextWitnessIdx++;
|
|
475
|
+
return idx;
|
|
476
|
+
}
|
|
477
|
+
if (expr.kind === "binary") {
|
|
478
|
+
const idx = this.nextWitnessIdx++;
|
|
479
|
+
this.processVariableInitBinary(idx, expr);
|
|
480
|
+
return idx;
|
|
481
|
+
}
|
|
482
|
+
if (expr.kind === "unary") {
|
|
483
|
+
const operandIdx = this.getOrCreateWitness(expr.operand);
|
|
484
|
+
if (expr.operator === "-") {
|
|
485
|
+
const idx = this.nextWitnessIdx++;
|
|
486
|
+
this.constraints.push({
|
|
487
|
+
a: [[this.NEG_ONE, operandIdx]],
|
|
488
|
+
b: [["0x1", 0]],
|
|
489
|
+
c: [["0x1", idx]]
|
|
490
|
+
});
|
|
491
|
+
return idx;
|
|
492
|
+
}
|
|
493
|
+
throw new Error(`Unsupported unary operator: ${expr.operator}`);
|
|
494
|
+
}
|
|
495
|
+
throw new Error(`Unsupported expression kind: ${expr.kind}`);
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
|
|
128
501
|
// src/infra/provingSystems/ArkworksWasm.ts
|
|
129
502
|
var ArkworksWasm_exports = {};
|
|
130
503
|
__export(ArkworksWasm_exports, {
|
|
@@ -258,6 +631,7 @@ var init_ArkworksWasm = __esm({
|
|
|
258
631
|
import_noir_wasm2 = require("@noir-lang/noir_wasm");
|
|
259
632
|
import_noir_js2 = require("@noir-lang/noir_js");
|
|
260
633
|
import_acvm_js = require("@noir-lang/acvm_js");
|
|
634
|
+
init_R1csBuilder();
|
|
261
635
|
import_meta = {};
|
|
262
636
|
wasmModule = null;
|
|
263
637
|
wasmInitPromise2 = null;
|
|
@@ -272,8 +646,11 @@ var init_ArkworksWasm = __esm({
|
|
|
272
646
|
}
|
|
273
647
|
/**
|
|
274
648
|
* Compile Noir code to a circuit with ACIR for Groth16 proving
|
|
649
|
+
*
|
|
650
|
+
* @param noirCode - The Noir source code to compile
|
|
651
|
+
* @param options - Optional compilation options including ParsedCircuit for dynamic R1CS
|
|
275
652
|
*/
|
|
276
|
-
async compile(noirCode) {
|
|
653
|
+
async compile(noirCode, options) {
|
|
277
654
|
const wasm = await initWasm();
|
|
278
655
|
const { basePath, cleanup } = await createTempDir2();
|
|
279
656
|
const fm = (0, import_noir_wasm2.createFileManager)(basePath);
|
|
@@ -298,36 +675,52 @@ authors = [""]
|
|
|
298
675
|
throw new Error("Compilation failed: no bytecode generated");
|
|
299
676
|
}
|
|
300
677
|
const parameters = compiled.abi.parameters;
|
|
301
|
-
|
|
302
|
-
const privateR1csIndices = [];
|
|
678
|
+
let r1cs;
|
|
303
679
|
const witnessIndexMapping = /* @__PURE__ */ new Map();
|
|
304
|
-
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
c: [["0x1", publicIdx]]
|
|
329
|
-
// expected
|
|
680
|
+
if (options?.parsedCircuit) {
|
|
681
|
+
const builder = new R1csBuilder(options.parsedCircuit);
|
|
682
|
+
r1cs = builder.build();
|
|
683
|
+
parameters.forEach((p, noirIndex) => {
|
|
684
|
+
const r1csIndex = noirIndex + 1;
|
|
685
|
+
witnessIndexMapping.set(noirIndex, r1csIndex);
|
|
686
|
+
});
|
|
687
|
+
console.log("=== R1CS BUILDER DEBUG ===");
|
|
688
|
+
console.log("ParsedCircuit publicParams:", options.parsedCircuit.publicParams);
|
|
689
|
+
console.log("ParsedCircuit privateParams:", options.parsedCircuit.privateParams);
|
|
690
|
+
console.log("ParsedCircuit statements:", JSON.stringify(options.parsedCircuit.statements, null, 2));
|
|
691
|
+
console.log("Generated R1CS:", JSON.stringify(r1cs, null, 2));
|
|
692
|
+
console.log("==========================");
|
|
693
|
+
} else {
|
|
694
|
+
const publicR1csIndices = [];
|
|
695
|
+
const privateR1csIndices = [];
|
|
696
|
+
parameters.forEach((p, noirIndex) => {
|
|
697
|
+
const r1csIndex = noirIndex + 1;
|
|
698
|
+
witnessIndexMapping.set(noirIndex, r1csIndex);
|
|
699
|
+
if (p.visibility === "public") {
|
|
700
|
+
publicR1csIndices.push(r1csIndex);
|
|
701
|
+
} else if (p.visibility === "private") {
|
|
702
|
+
privateR1csIndices.push(r1csIndex);
|
|
703
|
+
}
|
|
330
704
|
});
|
|
705
|
+
r1cs = {
|
|
706
|
+
num_witnesses: parameters.length + 1,
|
|
707
|
+
public_inputs: publicR1csIndices,
|
|
708
|
+
private_inputs: privateR1csIndices,
|
|
709
|
+
constraints: []
|
|
710
|
+
};
|
|
711
|
+
if (privateR1csIndices.length === 1 && publicR1csIndices.length === 1) {
|
|
712
|
+
const privateIdx = privateR1csIndices[0];
|
|
713
|
+
const publicIdx = publicR1csIndices[0];
|
|
714
|
+
r1cs.constraints.push({
|
|
715
|
+
a: [["0x1", privateIdx]],
|
|
716
|
+
b: [["0x1", privateIdx]],
|
|
717
|
+
c: [["0x1", publicIdx]]
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
console.log("=== R1CS HARDCODED DEBUG ===");
|
|
721
|
+
console.log("Using hardcoded R1CS pattern (no ParsedCircuit provided)");
|
|
722
|
+
console.log("R1CS:", JSON.stringify(r1cs, null, 2));
|
|
723
|
+
console.log("============================");
|
|
331
724
|
}
|
|
332
725
|
const r1csJson = JSON.stringify(r1cs);
|
|
333
726
|
let provingKey;
|
|
@@ -344,7 +737,7 @@ authors = [""]
|
|
|
344
737
|
}
|
|
345
738
|
}
|
|
346
739
|
const acirJson = JSON.stringify({
|
|
347
|
-
functions: [{ current_witness_index: parameters.length, opcodes: [], private_parameters:
|
|
740
|
+
functions: [{ current_witness_index: parameters.length, opcodes: [], private_parameters: r1cs.private_inputs, public_parameters: { witnesses: r1cs.public_inputs }, return_values: { witnesses: [] } }]
|
|
348
741
|
});
|
|
349
742
|
const arkworksCircuit = {
|
|
350
743
|
...compiled,
|
|
@@ -392,6 +785,7 @@ authors = [""]
|
|
|
392
785
|
circuit.verifyingKey = setupResult.verifying_key;
|
|
393
786
|
circuit.verifyingKeyGnark = setupResult.verifying_key_gnark;
|
|
394
787
|
}
|
|
788
|
+
const toHex = (arr) => Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
395
789
|
console.log("=== ARKWORKS PROVE DEBUG ===");
|
|
396
790
|
console.log("Witness JSON:", witnessJson);
|
|
397
791
|
console.log("R1CS JSON:", circuit.r1csJson);
|
|
@@ -400,7 +794,7 @@ authors = [""]
|
|
|
400
794
|
console.log("Proof gnark base64 length:", proofResult.proof_gnark.length);
|
|
401
795
|
const proofBytes = base64ToUint8Array(proofResult.proof_gnark);
|
|
402
796
|
console.log("Proof bytes length:", proofBytes.length);
|
|
403
|
-
console.log("Proof bytes hex:",
|
|
797
|
+
console.log("Proof bytes hex:", toHex(proofBytes));
|
|
404
798
|
console.log("============================");
|
|
405
799
|
return {
|
|
406
800
|
proof: proofBytes,
|
|
@@ -579,6 +973,7 @@ __export(index_exports, {
|
|
|
579
973
|
Network: () => Network,
|
|
580
974
|
OffchainVerifier: () => OffchainVerifier,
|
|
581
975
|
Provider: () => Provider,
|
|
976
|
+
R1csBuilder: () => R1csBuilder,
|
|
582
977
|
SolanaFormatter: () => SolanaFormatter,
|
|
583
978
|
SolanaTransactionBuilder: () => SolanaTransactionBuilder,
|
|
584
979
|
VkDeploymentManager: () => VkDeploymentManager,
|
|
@@ -1192,16 +1587,20 @@ var IziNoir = class _IziNoir {
|
|
|
1192
1587
|
* After compile(), the verifying key is available via `this.vk`.
|
|
1193
1588
|
*
|
|
1194
1589
|
* @param noirCode - The Noir source code to compile
|
|
1590
|
+
* @param options - Optional compilation options including ParsedCircuit for dynamic R1CS
|
|
1195
1591
|
* @returns CompileResult with circuit and verifying key
|
|
1196
1592
|
*
|
|
1197
1593
|
* @example
|
|
1198
1594
|
* ```typescript
|
|
1595
|
+
* // Basic usage
|
|
1199
1596
|
* const { circuit, verifyingKey } = await izi.compile(noirCode);
|
|
1200
|
-
*
|
|
1597
|
+
*
|
|
1598
|
+
* // With ParsedCircuit for dynamic R1CS generation
|
|
1599
|
+
* const { circuit } = await izi.compile(noirCode, { parsedCircuit });
|
|
1201
1600
|
* ```
|
|
1202
1601
|
*/
|
|
1203
|
-
async compile(noirCode) {
|
|
1204
|
-
this.compiledCircuit = await this.provingSystem.compile(noirCode);
|
|
1602
|
+
async compile(noirCode, options) {
|
|
1603
|
+
this.compiledCircuit = await this.provingSystem.compile(noirCode, options);
|
|
1205
1604
|
const vk = await this.extractVerifyingKey(this.compiledCircuit);
|
|
1206
1605
|
if (vk) {
|
|
1207
1606
|
this._verifyingKey = vk;
|
|
@@ -1416,14 +1815,15 @@ var IziNoir = class _IziNoir {
|
|
|
1416
1815
|
const connection = new Connection(networkConfig.rpcUrl, "confirmed");
|
|
1417
1816
|
const vkKeypair = Keypair.generate();
|
|
1418
1817
|
const authority = wallet.publicKey;
|
|
1818
|
+
const toHex = (arr) => Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1419
1819
|
console.log("=== DEPLOY VK DEBUG ===");
|
|
1420
1820
|
console.log("VK nrPublicInputs:", proofData.verifyingKey.nrPublicInputs);
|
|
1421
1821
|
console.log("VK bytes length:", proofData.verifyingKey.bytes.length);
|
|
1422
|
-
console.log("VK bytes (first 64 - alpha_g1):",
|
|
1423
|
-
console.log("VK bytes (64-192 - beta_g2):",
|
|
1424
|
-
console.log("VK bytes (192-320 - gamma_g2):",
|
|
1425
|
-
console.log("VK bytes (320-448 - delta_g2):",
|
|
1426
|
-
console.log("VK bytes (448+ - k elements):",
|
|
1822
|
+
console.log("VK bytes (first 64 - alpha_g1):", toHex(proofData.verifyingKey.bytes.slice(0, 64)));
|
|
1823
|
+
console.log("VK bytes (64-192 - beta_g2):", toHex(proofData.verifyingKey.bytes.slice(64, 192)));
|
|
1824
|
+
console.log("VK bytes (192-320 - gamma_g2):", toHex(proofData.verifyingKey.bytes.slice(192, 320)));
|
|
1825
|
+
console.log("VK bytes (320-448 - delta_g2):", toHex(proofData.verifyingKey.bytes.slice(320, 448)));
|
|
1826
|
+
console.log("VK bytes (448+ - k elements):", toHex(proofData.verifyingKey.bytes.slice(448)));
|
|
1427
1827
|
console.log("=======================");
|
|
1428
1828
|
const builder = new SolanaTransactionBuilder({
|
|
1429
1829
|
programId: networkConfig.programId,
|
|
@@ -1515,16 +1915,17 @@ var IziNoir = class _IziNoir {
|
|
|
1515
1915
|
`VK account ${vk} has invalid data (${accountInfo.data.length} bytes). Expected at least 8 bytes for a valid account.`
|
|
1516
1916
|
);
|
|
1517
1917
|
}
|
|
1918
|
+
const toHex = (arr) => Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1518
1919
|
console.log("=== VERIFY ON-CHAIN DEBUG ===");
|
|
1519
1920
|
console.log("VK Account:", vk);
|
|
1520
1921
|
console.log("VK Account data length:", accountInfo.data.length, "bytes");
|
|
1521
1922
|
console.log("Proof size:", proofData.proof.bytes.length, "bytes");
|
|
1522
|
-
console.log("Proof (first 64 bytes - A point):",
|
|
1523
|
-
console.log("Proof (bytes 64-192 - B point):",
|
|
1524
|
-
console.log("Proof (bytes 192-256 - C point):",
|
|
1923
|
+
console.log("Proof (first 64 bytes - A point):", toHex(proofData.proof.bytes.slice(0, 64)));
|
|
1924
|
+
console.log("Proof (bytes 64-192 - B point):", toHex(proofData.proof.bytes.slice(64, 192)));
|
|
1925
|
+
console.log("Proof (bytes 192-256 - C point):", toHex(proofData.proof.bytes.slice(192, 256)));
|
|
1525
1926
|
console.log("Public inputs count:", proofData.publicInputs.bytes.length);
|
|
1526
1927
|
proofData.publicInputs.bytes.forEach((input, i) => {
|
|
1527
|
-
console.log(` Public input[${i}]:`,
|
|
1928
|
+
console.log(` Public input[${i}]:`, toHex(input));
|
|
1528
1929
|
});
|
|
1529
1930
|
console.log("Public inputs hex:", proofData.publicInputs.hex);
|
|
1530
1931
|
console.log("VK nrPublicInputs:", proofData.verifyingKey.nrPublicInputs);
|
|
@@ -1622,6 +2023,7 @@ Check on explorer: ${getExplorerTxUrl(this._network, signature)}`
|
|
|
1622
2023
|
init_SolanaFormatter();
|
|
1623
2024
|
init_Barretenberg();
|
|
1624
2025
|
init_ArkworksWasm();
|
|
2026
|
+
init_R1csBuilder();
|
|
1625
2027
|
|
|
1626
2028
|
// src/infra/parser/AcornParser.ts
|
|
1627
2029
|
var acorn = __toESM(require("acorn"), 1);
|
|
@@ -3166,6 +3568,7 @@ function defineConfig(config) {
|
|
|
3166
3568
|
Network,
|
|
3167
3569
|
OffchainVerifier,
|
|
3168
3570
|
Provider,
|
|
3571
|
+
R1csBuilder,
|
|
3169
3572
|
SolanaFormatter,
|
|
3170
3573
|
SolanaTransactionBuilder,
|
|
3171
3574
|
VkDeploymentManager,
|