@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.js
CHANGED
|
@@ -45,7 +45,9 @@ var init_Barretenberg = __esm({
|
|
|
45
45
|
"src/infra/provingSystems/Barretenberg.ts"() {
|
|
46
46
|
"use strict";
|
|
47
47
|
Barretenberg = class {
|
|
48
|
-
|
|
48
|
+
// Note: options parameter is accepted but not used - Barretenberg uses Noir's ACIR directly
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
50
|
+
async compile(noirCode, _options) {
|
|
49
51
|
const { basePath, cleanup } = await createTempDir();
|
|
50
52
|
const fm = createFileManager(basePath);
|
|
51
53
|
const nargoToml = `[package]
|
|
@@ -103,6 +105,377 @@ authors = [""]
|
|
|
103
105
|
}
|
|
104
106
|
});
|
|
105
107
|
|
|
108
|
+
// src/infra/provingSystems/R1csBuilder.ts
|
|
109
|
+
var R1csBuilder;
|
|
110
|
+
var init_R1csBuilder = __esm({
|
|
111
|
+
"src/infra/provingSystems/R1csBuilder.ts"() {
|
|
112
|
+
"use strict";
|
|
113
|
+
R1csBuilder = class {
|
|
114
|
+
constructor(parsedCircuit) {
|
|
115
|
+
this.parsedCircuit = parsedCircuit;
|
|
116
|
+
}
|
|
117
|
+
constraints = [];
|
|
118
|
+
witnessMap = /* @__PURE__ */ new Map();
|
|
119
|
+
nextWitnessIdx = 1;
|
|
120
|
+
// w_0 = 1 is reserved
|
|
121
|
+
publicIndices = [];
|
|
122
|
+
privateIndices = [];
|
|
123
|
+
// BN254 scalar field modulus - 1 (for representing -1)
|
|
124
|
+
// Fr modulus = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
|
125
|
+
// -1 mod Fr = Fr - 1
|
|
126
|
+
NEG_ONE = "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000";
|
|
127
|
+
/**
|
|
128
|
+
* Build R1CS definition from the parsed circuit
|
|
129
|
+
*/
|
|
130
|
+
build() {
|
|
131
|
+
this.registerInputs();
|
|
132
|
+
for (const stmt of this.parsedCircuit.statements) {
|
|
133
|
+
this.processStatement(stmt);
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
num_witnesses: this.nextWitnessIdx,
|
|
137
|
+
public_inputs: this.publicIndices,
|
|
138
|
+
private_inputs: this.privateIndices,
|
|
139
|
+
constraints: this.constraints
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get the witness index for an input parameter name
|
|
144
|
+
*/
|
|
145
|
+
getWitnessIndex(name) {
|
|
146
|
+
return this.witnessMap.get(name);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Register all circuit inputs as witnesses
|
|
150
|
+
* Public inputs come first, then private inputs
|
|
151
|
+
*/
|
|
152
|
+
registerInputs() {
|
|
153
|
+
for (const param of this.parsedCircuit.publicParams) {
|
|
154
|
+
const idx = this.nextWitnessIdx++;
|
|
155
|
+
this.witnessMap.set(param.name, idx);
|
|
156
|
+
this.publicIndices.push(idx);
|
|
157
|
+
}
|
|
158
|
+
for (const param of this.parsedCircuit.privateParams) {
|
|
159
|
+
const idx = this.nextWitnessIdx++;
|
|
160
|
+
this.witnessMap.set(param.name, idx);
|
|
161
|
+
this.privateIndices.push(idx);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Process a single statement and generate constraints
|
|
166
|
+
*/
|
|
167
|
+
processStatement(stmt) {
|
|
168
|
+
switch (stmt.kind) {
|
|
169
|
+
case "assert":
|
|
170
|
+
this.processAssert(stmt.condition);
|
|
171
|
+
break;
|
|
172
|
+
case "variable_declaration":
|
|
173
|
+
this.processVariableDecl(stmt.name, stmt.initializer);
|
|
174
|
+
break;
|
|
175
|
+
case "assignment":
|
|
176
|
+
this.processAssignment(stmt.target, stmt.value);
|
|
177
|
+
break;
|
|
178
|
+
case "if_statement":
|
|
179
|
+
for (const s of stmt.consequent) {
|
|
180
|
+
this.processStatement(s);
|
|
181
|
+
}
|
|
182
|
+
if (stmt.alternate) {
|
|
183
|
+
for (const s of stmt.alternate) {
|
|
184
|
+
this.processStatement(s);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
break;
|
|
188
|
+
case "for_statement":
|
|
189
|
+
throw new Error(
|
|
190
|
+
"For loops are not yet supported in R1CS generation. Use the Barretenberg backend for complex circuits."
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Process an assert statement
|
|
196
|
+
* The condition must evaluate to true for a valid proof
|
|
197
|
+
*/
|
|
198
|
+
processAssert(condition) {
|
|
199
|
+
if (condition.kind === "binary") {
|
|
200
|
+
this.processBinaryAssert(condition);
|
|
201
|
+
} else if (condition.kind === "identifier") {
|
|
202
|
+
const idx = this.getOrCreateWitness(condition);
|
|
203
|
+
this.constraints.push({
|
|
204
|
+
a: [["0x1", idx]],
|
|
205
|
+
b: [["0x1", 0]],
|
|
206
|
+
// * 1
|
|
207
|
+
c: [["0x1", 0]]
|
|
208
|
+
// = 1 (w_0)
|
|
209
|
+
});
|
|
210
|
+
} else {
|
|
211
|
+
throw new Error(`Unsupported assert condition kind: ${condition.kind}`);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Process a binary expression in an assert
|
|
216
|
+
*/
|
|
217
|
+
processBinaryAssert(expr) {
|
|
218
|
+
const { left, operator, right } = expr;
|
|
219
|
+
switch (operator) {
|
|
220
|
+
case "==":
|
|
221
|
+
this.processEquality(left, right);
|
|
222
|
+
break;
|
|
223
|
+
case "!=":
|
|
224
|
+
throw new Error(
|
|
225
|
+
"Inequality (!=) is not yet supported in R1CS. Use equality (==) instead."
|
|
226
|
+
);
|
|
227
|
+
case "+":
|
|
228
|
+
case "-":
|
|
229
|
+
case "*":
|
|
230
|
+
case "/":
|
|
231
|
+
case "%":
|
|
232
|
+
throw new Error(
|
|
233
|
+
`Arithmetic operator ${operator} must be part of an equality assertion. Use: assert(a ${operator} b == c)`
|
|
234
|
+
);
|
|
235
|
+
case "<":
|
|
236
|
+
case ">":
|
|
237
|
+
case "<=":
|
|
238
|
+
case ">=":
|
|
239
|
+
throw new Error(
|
|
240
|
+
`Comparison operators (${operator}) require range proofs which are not yet supported. Use the Barretenberg backend for comparison operations.`
|
|
241
|
+
);
|
|
242
|
+
case "&":
|
|
243
|
+
case "|":
|
|
244
|
+
throw new Error(
|
|
245
|
+
`Logical operator ${operator} is not yet supported in R1CS.`
|
|
246
|
+
);
|
|
247
|
+
default:
|
|
248
|
+
throw new Error(`Unsupported operator in assert: ${operator}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Process an equality assertion: assert(left == right)
|
|
253
|
+
*/
|
|
254
|
+
processEquality(left, right) {
|
|
255
|
+
if (left.kind === "binary" && left.operator === "*") {
|
|
256
|
+
this.processMultiplicationEquality(left.left, left.right, right);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (right.kind === "binary" && right.operator === "*") {
|
|
260
|
+
this.processMultiplicationEquality(right.left, right.right, left);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
if (left.kind === "binary" && left.operator === "+") {
|
|
264
|
+
this.processAdditionEquality(left.left, left.right, right);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (right.kind === "binary" && right.operator === "+") {
|
|
268
|
+
this.processAdditionEquality(right.left, right.right, left);
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
if (left.kind === "binary" && left.operator === "-") {
|
|
272
|
+
this.processSubtractionEquality(left.left, left.right, right);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (right.kind === "binary" && right.operator === "-") {
|
|
276
|
+
this.processSubtractionEquality(right.left, right.right, left);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const leftIdx = this.getOrCreateWitness(left);
|
|
280
|
+
const rightIdx = this.getOrCreateWitness(right);
|
|
281
|
+
this.constraints.push({
|
|
282
|
+
a: [
|
|
283
|
+
["0x1", leftIdx],
|
|
284
|
+
[this.NEG_ONE, rightIdx]
|
|
285
|
+
],
|
|
286
|
+
// a - b
|
|
287
|
+
b: [["0x1", 0]],
|
|
288
|
+
// * 1 (w_0 = 1)
|
|
289
|
+
c: []
|
|
290
|
+
// = 0
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Process multiplication equality: assert(a * b == c)
|
|
295
|
+
* R1CS: a * b = c
|
|
296
|
+
*/
|
|
297
|
+
processMultiplicationEquality(left, right, result) {
|
|
298
|
+
const leftIdx = this.getOrCreateWitness(left);
|
|
299
|
+
const rightIdx = this.getOrCreateWitness(right);
|
|
300
|
+
const resultIdx = this.getOrCreateWitness(result);
|
|
301
|
+
this.constraints.push({
|
|
302
|
+
a: [["0x1", leftIdx]],
|
|
303
|
+
b: [["0x1", rightIdx]],
|
|
304
|
+
c: [["0x1", resultIdx]]
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Process addition equality: assert(a + b == c)
|
|
309
|
+
* R1CS: (a + b - c) * 1 = 0
|
|
310
|
+
* Which is: (a + b) * 1 = c
|
|
311
|
+
*/
|
|
312
|
+
processAdditionEquality(left, right, result) {
|
|
313
|
+
const leftIdx = this.getOrCreateWitness(left);
|
|
314
|
+
const rightIdx = this.getOrCreateWitness(right);
|
|
315
|
+
const resultIdx = this.getOrCreateWitness(result);
|
|
316
|
+
this.constraints.push({
|
|
317
|
+
a: [
|
|
318
|
+
["0x1", leftIdx],
|
|
319
|
+
["0x1", rightIdx]
|
|
320
|
+
],
|
|
321
|
+
// a + b
|
|
322
|
+
b: [["0x1", 0]],
|
|
323
|
+
// * 1
|
|
324
|
+
c: [["0x1", resultIdx]]
|
|
325
|
+
// = c
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Process subtraction equality: assert(a - b == c)
|
|
330
|
+
* R1CS: (a - b) * 1 = c
|
|
331
|
+
*/
|
|
332
|
+
processSubtractionEquality(left, right, result) {
|
|
333
|
+
const leftIdx = this.getOrCreateWitness(left);
|
|
334
|
+
const rightIdx = this.getOrCreateWitness(right);
|
|
335
|
+
const resultIdx = this.getOrCreateWitness(result);
|
|
336
|
+
this.constraints.push({
|
|
337
|
+
a: [
|
|
338
|
+
["0x1", leftIdx],
|
|
339
|
+
[this.NEG_ONE, rightIdx]
|
|
340
|
+
],
|
|
341
|
+
// a - b
|
|
342
|
+
b: [["0x1", 0]],
|
|
343
|
+
// * 1
|
|
344
|
+
c: [["0x1", resultIdx]]
|
|
345
|
+
// = c
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Process a variable declaration: let x = expr
|
|
350
|
+
* Creates a new witness for x and adds constraint if needed
|
|
351
|
+
*/
|
|
352
|
+
processVariableDecl(name, initializer) {
|
|
353
|
+
const varIdx = this.nextWitnessIdx++;
|
|
354
|
+
this.witnessMap.set(name, varIdx);
|
|
355
|
+
if (initializer.kind === "identifier") {
|
|
356
|
+
const initIdx = this.getOrCreateWitness(initializer);
|
|
357
|
+
this.constraints.push({
|
|
358
|
+
a: [
|
|
359
|
+
["0x1", varIdx],
|
|
360
|
+
[this.NEG_ONE, initIdx]
|
|
361
|
+
],
|
|
362
|
+
b: [["0x1", 0]],
|
|
363
|
+
c: []
|
|
364
|
+
});
|
|
365
|
+
} else if (initializer.kind === "literal") {
|
|
366
|
+
} else if (initializer.kind === "binary") {
|
|
367
|
+
this.processVariableInitBinary(varIdx, initializer);
|
|
368
|
+
} else {
|
|
369
|
+
throw new Error(
|
|
370
|
+
`Unsupported initializer kind for variable declaration: ${initializer.kind}`
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Process a binary expression as variable initializer
|
|
376
|
+
*/
|
|
377
|
+
processVariableInitBinary(varIdx, expr) {
|
|
378
|
+
const { left, operator, right } = expr;
|
|
379
|
+
const leftIdx = this.getOrCreateWitness(left);
|
|
380
|
+
const rightIdx = this.getOrCreateWitness(right);
|
|
381
|
+
switch (operator) {
|
|
382
|
+
case "*":
|
|
383
|
+
this.constraints.push({
|
|
384
|
+
a: [["0x1", leftIdx]],
|
|
385
|
+
b: [["0x1", rightIdx]],
|
|
386
|
+
c: [["0x1", varIdx]]
|
|
387
|
+
});
|
|
388
|
+
break;
|
|
389
|
+
case "+":
|
|
390
|
+
this.constraints.push({
|
|
391
|
+
a: [
|
|
392
|
+
["0x1", leftIdx],
|
|
393
|
+
["0x1", rightIdx]
|
|
394
|
+
],
|
|
395
|
+
b: [["0x1", 0]],
|
|
396
|
+
c: [["0x1", varIdx]]
|
|
397
|
+
});
|
|
398
|
+
break;
|
|
399
|
+
case "-":
|
|
400
|
+
this.constraints.push({
|
|
401
|
+
a: [
|
|
402
|
+
["0x1", leftIdx],
|
|
403
|
+
[this.NEG_ONE, rightIdx]
|
|
404
|
+
],
|
|
405
|
+
b: [["0x1", 0]],
|
|
406
|
+
c: [["0x1", varIdx]]
|
|
407
|
+
});
|
|
408
|
+
break;
|
|
409
|
+
default:
|
|
410
|
+
throw new Error(
|
|
411
|
+
`Unsupported operator in variable initializer: ${operator}`
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Process an assignment: x = expr
|
|
417
|
+
* Updates the witness mapping
|
|
418
|
+
*/
|
|
419
|
+
processAssignment(target, value) {
|
|
420
|
+
const existingIdx = this.witnessMap.get(target);
|
|
421
|
+
if (existingIdx === void 0) {
|
|
422
|
+
throw new Error(`Assignment to undeclared variable: ${target}`);
|
|
423
|
+
}
|
|
424
|
+
if (value.kind === "identifier") {
|
|
425
|
+
const valueIdx = this.getOrCreateWitness(value);
|
|
426
|
+
this.constraints.push({
|
|
427
|
+
a: [
|
|
428
|
+
["0x1", existingIdx],
|
|
429
|
+
[this.NEG_ONE, valueIdx]
|
|
430
|
+
],
|
|
431
|
+
b: [["0x1", 0]],
|
|
432
|
+
c: []
|
|
433
|
+
});
|
|
434
|
+
} else if (value.kind === "binary") {
|
|
435
|
+
this.processVariableInitBinary(existingIdx, value);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Get or create a witness index for an expression
|
|
440
|
+
*/
|
|
441
|
+
getOrCreateWitness(expr) {
|
|
442
|
+
if (expr.kind === "identifier") {
|
|
443
|
+
const existing = this.witnessMap.get(expr.name);
|
|
444
|
+
if (existing !== void 0) {
|
|
445
|
+
return existing;
|
|
446
|
+
}
|
|
447
|
+
const idx = this.nextWitnessIdx++;
|
|
448
|
+
this.witnessMap.set(expr.name, idx);
|
|
449
|
+
return idx;
|
|
450
|
+
}
|
|
451
|
+
if (expr.kind === "literal") {
|
|
452
|
+
const idx = this.nextWitnessIdx++;
|
|
453
|
+
return idx;
|
|
454
|
+
}
|
|
455
|
+
if (expr.kind === "binary") {
|
|
456
|
+
const idx = this.nextWitnessIdx++;
|
|
457
|
+
this.processVariableInitBinary(idx, expr);
|
|
458
|
+
return idx;
|
|
459
|
+
}
|
|
460
|
+
if (expr.kind === "unary") {
|
|
461
|
+
const operandIdx = this.getOrCreateWitness(expr.operand);
|
|
462
|
+
if (expr.operator === "-") {
|
|
463
|
+
const idx = this.nextWitnessIdx++;
|
|
464
|
+
this.constraints.push({
|
|
465
|
+
a: [[this.NEG_ONE, operandIdx]],
|
|
466
|
+
b: [["0x1", 0]],
|
|
467
|
+
c: [["0x1", idx]]
|
|
468
|
+
});
|
|
469
|
+
return idx;
|
|
470
|
+
}
|
|
471
|
+
throw new Error(`Unsupported unary operator: ${expr.operator}`);
|
|
472
|
+
}
|
|
473
|
+
throw new Error(`Unsupported expression kind: ${expr.kind}`);
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
|
|
106
479
|
// src/infra/provingSystems/ArkworksWasm.ts
|
|
107
480
|
var ArkworksWasm_exports = {};
|
|
108
481
|
__export(ArkworksWasm_exports, {
|
|
@@ -236,6 +609,7 @@ var wasmModule, wasmInitPromise2, ArkworksWasm;
|
|
|
236
609
|
var init_ArkworksWasm = __esm({
|
|
237
610
|
"src/infra/provingSystems/ArkworksWasm.ts"() {
|
|
238
611
|
"use strict";
|
|
612
|
+
init_R1csBuilder();
|
|
239
613
|
wasmModule = null;
|
|
240
614
|
wasmInitPromise2 = null;
|
|
241
615
|
ArkworksWasm = class {
|
|
@@ -249,8 +623,11 @@ var init_ArkworksWasm = __esm({
|
|
|
249
623
|
}
|
|
250
624
|
/**
|
|
251
625
|
* Compile Noir code to a circuit with ACIR for Groth16 proving
|
|
626
|
+
*
|
|
627
|
+
* @param noirCode - The Noir source code to compile
|
|
628
|
+
* @param options - Optional compilation options including ParsedCircuit for dynamic R1CS
|
|
252
629
|
*/
|
|
253
|
-
async compile(noirCode) {
|
|
630
|
+
async compile(noirCode, options) {
|
|
254
631
|
const wasm = await initWasm();
|
|
255
632
|
const { basePath, cleanup } = await createTempDir2();
|
|
256
633
|
const fm = createFileManager2(basePath);
|
|
@@ -275,36 +652,52 @@ authors = [""]
|
|
|
275
652
|
throw new Error("Compilation failed: no bytecode generated");
|
|
276
653
|
}
|
|
277
654
|
const parameters = compiled.abi.parameters;
|
|
278
|
-
|
|
279
|
-
const privateR1csIndices = [];
|
|
655
|
+
let r1cs;
|
|
280
656
|
const witnessIndexMapping = /* @__PURE__ */ new Map();
|
|
281
|
-
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
c: [["0x1", publicIdx]]
|
|
306
|
-
// expected
|
|
657
|
+
if (options?.parsedCircuit) {
|
|
658
|
+
const builder = new R1csBuilder(options.parsedCircuit);
|
|
659
|
+
r1cs = builder.build();
|
|
660
|
+
parameters.forEach((p, noirIndex) => {
|
|
661
|
+
const r1csIndex = noirIndex + 1;
|
|
662
|
+
witnessIndexMapping.set(noirIndex, r1csIndex);
|
|
663
|
+
});
|
|
664
|
+
console.log("=== R1CS BUILDER DEBUG ===");
|
|
665
|
+
console.log("ParsedCircuit publicParams:", options.parsedCircuit.publicParams);
|
|
666
|
+
console.log("ParsedCircuit privateParams:", options.parsedCircuit.privateParams);
|
|
667
|
+
console.log("ParsedCircuit statements:", JSON.stringify(options.parsedCircuit.statements, null, 2));
|
|
668
|
+
console.log("Generated R1CS:", JSON.stringify(r1cs, null, 2));
|
|
669
|
+
console.log("==========================");
|
|
670
|
+
} else {
|
|
671
|
+
const publicR1csIndices = [];
|
|
672
|
+
const privateR1csIndices = [];
|
|
673
|
+
parameters.forEach((p, noirIndex) => {
|
|
674
|
+
const r1csIndex = noirIndex + 1;
|
|
675
|
+
witnessIndexMapping.set(noirIndex, r1csIndex);
|
|
676
|
+
if (p.visibility === "public") {
|
|
677
|
+
publicR1csIndices.push(r1csIndex);
|
|
678
|
+
} else if (p.visibility === "private") {
|
|
679
|
+
privateR1csIndices.push(r1csIndex);
|
|
680
|
+
}
|
|
307
681
|
});
|
|
682
|
+
r1cs = {
|
|
683
|
+
num_witnesses: parameters.length + 1,
|
|
684
|
+
public_inputs: publicR1csIndices,
|
|
685
|
+
private_inputs: privateR1csIndices,
|
|
686
|
+
constraints: []
|
|
687
|
+
};
|
|
688
|
+
if (privateR1csIndices.length === 1 && publicR1csIndices.length === 1) {
|
|
689
|
+
const privateIdx = privateR1csIndices[0];
|
|
690
|
+
const publicIdx = publicR1csIndices[0];
|
|
691
|
+
r1cs.constraints.push({
|
|
692
|
+
a: [["0x1", privateIdx]],
|
|
693
|
+
b: [["0x1", privateIdx]],
|
|
694
|
+
c: [["0x1", publicIdx]]
|
|
695
|
+
});
|
|
696
|
+
}
|
|
697
|
+
console.log("=== R1CS HARDCODED DEBUG ===");
|
|
698
|
+
console.log("Using hardcoded R1CS pattern (no ParsedCircuit provided)");
|
|
699
|
+
console.log("R1CS:", JSON.stringify(r1cs, null, 2));
|
|
700
|
+
console.log("============================");
|
|
308
701
|
}
|
|
309
702
|
const r1csJson = JSON.stringify(r1cs);
|
|
310
703
|
let provingKey;
|
|
@@ -321,7 +714,7 @@ authors = [""]
|
|
|
321
714
|
}
|
|
322
715
|
}
|
|
323
716
|
const acirJson = JSON.stringify({
|
|
324
|
-
functions: [{ current_witness_index: parameters.length, opcodes: [], private_parameters:
|
|
717
|
+
functions: [{ current_witness_index: parameters.length, opcodes: [], private_parameters: r1cs.private_inputs, public_parameters: { witnesses: r1cs.public_inputs }, return_values: { witnesses: [] } }]
|
|
325
718
|
});
|
|
326
719
|
const arkworksCircuit = {
|
|
327
720
|
...compiled,
|
|
@@ -369,6 +762,7 @@ authors = [""]
|
|
|
369
762
|
circuit.verifyingKey = setupResult.verifying_key;
|
|
370
763
|
circuit.verifyingKeyGnark = setupResult.verifying_key_gnark;
|
|
371
764
|
}
|
|
765
|
+
const toHex = (arr) => Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
372
766
|
console.log("=== ARKWORKS PROVE DEBUG ===");
|
|
373
767
|
console.log("Witness JSON:", witnessJson);
|
|
374
768
|
console.log("R1CS JSON:", circuit.r1csJson);
|
|
@@ -377,7 +771,7 @@ authors = [""]
|
|
|
377
771
|
console.log("Proof gnark base64 length:", proofResult.proof_gnark.length);
|
|
378
772
|
const proofBytes = base64ToUint8Array(proofResult.proof_gnark);
|
|
379
773
|
console.log("Proof bytes length:", proofBytes.length);
|
|
380
|
-
console.log("Proof bytes hex:",
|
|
774
|
+
console.log("Proof bytes hex:", toHex(proofBytes));
|
|
381
775
|
console.log("============================");
|
|
382
776
|
return {
|
|
383
777
|
proof: proofBytes,
|
|
@@ -1124,16 +1518,20 @@ var IziNoir = class _IziNoir {
|
|
|
1124
1518
|
* After compile(), the verifying key is available via `this.vk`.
|
|
1125
1519
|
*
|
|
1126
1520
|
* @param noirCode - The Noir source code to compile
|
|
1521
|
+
* @param options - Optional compilation options including ParsedCircuit for dynamic R1CS
|
|
1127
1522
|
* @returns CompileResult with circuit and verifying key
|
|
1128
1523
|
*
|
|
1129
1524
|
* @example
|
|
1130
1525
|
* ```typescript
|
|
1526
|
+
* // Basic usage
|
|
1131
1527
|
* const { circuit, verifyingKey } = await izi.compile(noirCode);
|
|
1132
|
-
*
|
|
1528
|
+
*
|
|
1529
|
+
* // With ParsedCircuit for dynamic R1CS generation
|
|
1530
|
+
* const { circuit } = await izi.compile(noirCode, { parsedCircuit });
|
|
1133
1531
|
* ```
|
|
1134
1532
|
*/
|
|
1135
|
-
async compile(noirCode) {
|
|
1136
|
-
this.compiledCircuit = await this.provingSystem.compile(noirCode);
|
|
1533
|
+
async compile(noirCode, options) {
|
|
1534
|
+
this.compiledCircuit = await this.provingSystem.compile(noirCode, options);
|
|
1137
1535
|
const vk = await this.extractVerifyingKey(this.compiledCircuit);
|
|
1138
1536
|
if (vk) {
|
|
1139
1537
|
this._verifyingKey = vk;
|
|
@@ -1348,14 +1746,15 @@ var IziNoir = class _IziNoir {
|
|
|
1348
1746
|
const connection = new Connection(networkConfig.rpcUrl, "confirmed");
|
|
1349
1747
|
const vkKeypair = Keypair.generate();
|
|
1350
1748
|
const authority = wallet.publicKey;
|
|
1749
|
+
const toHex = (arr) => Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1351
1750
|
console.log("=== DEPLOY VK DEBUG ===");
|
|
1352
1751
|
console.log("VK nrPublicInputs:", proofData.verifyingKey.nrPublicInputs);
|
|
1353
1752
|
console.log("VK bytes length:", proofData.verifyingKey.bytes.length);
|
|
1354
|
-
console.log("VK bytes (first 64 - alpha_g1):",
|
|
1355
|
-
console.log("VK bytes (64-192 - beta_g2):",
|
|
1356
|
-
console.log("VK bytes (192-320 - gamma_g2):",
|
|
1357
|
-
console.log("VK bytes (320-448 - delta_g2):",
|
|
1358
|
-
console.log("VK bytes (448+ - k elements):",
|
|
1753
|
+
console.log("VK bytes (first 64 - alpha_g1):", toHex(proofData.verifyingKey.bytes.slice(0, 64)));
|
|
1754
|
+
console.log("VK bytes (64-192 - beta_g2):", toHex(proofData.verifyingKey.bytes.slice(64, 192)));
|
|
1755
|
+
console.log("VK bytes (192-320 - gamma_g2):", toHex(proofData.verifyingKey.bytes.slice(192, 320)));
|
|
1756
|
+
console.log("VK bytes (320-448 - delta_g2):", toHex(proofData.verifyingKey.bytes.slice(320, 448)));
|
|
1757
|
+
console.log("VK bytes (448+ - k elements):", toHex(proofData.verifyingKey.bytes.slice(448)));
|
|
1359
1758
|
console.log("=======================");
|
|
1360
1759
|
const builder = new SolanaTransactionBuilder({
|
|
1361
1760
|
programId: networkConfig.programId,
|
|
@@ -1447,16 +1846,17 @@ var IziNoir = class _IziNoir {
|
|
|
1447
1846
|
`VK account ${vk} has invalid data (${accountInfo.data.length} bytes). Expected at least 8 bytes for a valid account.`
|
|
1448
1847
|
);
|
|
1449
1848
|
}
|
|
1849
|
+
const toHex = (arr) => Array.from(arr).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1450
1850
|
console.log("=== VERIFY ON-CHAIN DEBUG ===");
|
|
1451
1851
|
console.log("VK Account:", vk);
|
|
1452
1852
|
console.log("VK Account data length:", accountInfo.data.length, "bytes");
|
|
1453
1853
|
console.log("Proof size:", proofData.proof.bytes.length, "bytes");
|
|
1454
|
-
console.log("Proof (first 64 bytes - A point):",
|
|
1455
|
-
console.log("Proof (bytes 64-192 - B point):",
|
|
1456
|
-
console.log("Proof (bytes 192-256 - C point):",
|
|
1854
|
+
console.log("Proof (first 64 bytes - A point):", toHex(proofData.proof.bytes.slice(0, 64)));
|
|
1855
|
+
console.log("Proof (bytes 64-192 - B point):", toHex(proofData.proof.bytes.slice(64, 192)));
|
|
1856
|
+
console.log("Proof (bytes 192-256 - C point):", toHex(proofData.proof.bytes.slice(192, 256)));
|
|
1457
1857
|
console.log("Public inputs count:", proofData.publicInputs.bytes.length);
|
|
1458
1858
|
proofData.publicInputs.bytes.forEach((input, i) => {
|
|
1459
|
-
console.log(` Public input[${i}]:`,
|
|
1859
|
+
console.log(` Public input[${i}]:`, toHex(input));
|
|
1460
1860
|
});
|
|
1461
1861
|
console.log("Public inputs hex:", proofData.publicInputs.hex);
|
|
1462
1862
|
console.log("VK nrPublicInputs:", proofData.verifyingKey.nrPublicInputs);
|
|
@@ -1554,6 +1954,7 @@ Check on explorer: ${getExplorerTxUrl(this._network, signature)}`
|
|
|
1554
1954
|
init_SolanaFormatter();
|
|
1555
1955
|
init_Barretenberg();
|
|
1556
1956
|
init_ArkworksWasm();
|
|
1957
|
+
init_R1csBuilder();
|
|
1557
1958
|
|
|
1558
1959
|
// src/infra/parser/AcornParser.ts
|
|
1559
1960
|
import * as acorn from "acorn";
|
|
@@ -3097,6 +3498,7 @@ export {
|
|
|
3097
3498
|
Network,
|
|
3098
3499
|
OffchainVerifier,
|
|
3099
3500
|
Provider,
|
|
3501
|
+
R1csBuilder,
|
|
3100
3502
|
SolanaFormatter,
|
|
3101
3503
|
SolanaTransactionBuilder,
|
|
3102
3504
|
VkDeploymentManager,
|