mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-07 03:06:42 +01:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b712f3587 | ||
|
|
26cad30222 | ||
|
|
f48de61ca9 | ||
|
|
89cea4755c | ||
|
|
9bf6ecc4f3 | ||
|
|
59d591c988 | ||
|
|
9fe8be9828 |
61
package-lock.json
generated
61
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "circom",
|
||||
"version": "0.5.13",
|
||||
"version": "0.5.16",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -143,6 +143,11 @@
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
|
||||
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
|
||||
},
|
||||
"blakejs": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz",
|
||||
"integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
@@ -571,9 +576,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"fastfile": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.2.tgz",
|
||||
"integrity": "sha512-rS9vpAM4DS+xacKSH0MVCqr/Y5SiIAiunJTYSuq1H9nfRpkP37ewgnjH3FztziKBUQB2xPYS/WxEEjHl+pA5Fg=="
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.8.tgz",
|
||||
"integrity": "sha512-i78nuMJUoNZP5J1bPjecK07+ifHMJTBnJND/4QMUYp++DDltoAjQcIeFIWoUalt7n324fvvzWR55+WEPQUA7tQ=="
|
||||
},
|
||||
"ffiasm": {
|
||||
"version": "0.0.2",
|
||||
@@ -586,11 +591,13 @@
|
||||
}
|
||||
},
|
||||
"ffjavascript": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.1.2.tgz",
|
||||
"integrity": "sha512-zB1dhgBjJlvyk2VQIQzFSpUJmanYQYDR/Fo1KhZnaNW5chMFJT55qz0dx1LMKrAklBbidKzz2/C7dgibxQF94g==",
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.4.tgz",
|
||||
"integrity": "sha512-XFeWcjUDFPavN+DDOxhE8p5MOhZQJc9oO1Sj4ml1pyjqNhS1ujEamcjFyK0cctdnat61i7lvpTYzdtS3RYDC8w==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.48"
|
||||
"big-integer": "^1.6.48",
|
||||
"wasmcurves": "0.0.4",
|
||||
"worker-threads": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"ffwasm": {
|
||||
@@ -1154,26 +1161,18 @@
|
||||
"dev": true
|
||||
},
|
||||
"r1csfile": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.5.tgz",
|
||||
"integrity": "sha512-B+BdKPb/WUTp4N/3X4d1Spgx9Ojx5tFVejGZRJxpTtzq34mC8Vi/czWfiPj85V8kud31lCfYcZ16z7+czvM0Sw==",
|
||||
"version": "0.0.14",
|
||||
"resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.14.tgz",
|
||||
"integrity": "sha512-7m4eWpnbjkwGGUaRmIAJc4w+HvaeBPJXUKHIqLkHeD9Yyjem6/EHmlgDVl+4hWNWGZqdhXuMqWSH9+O6QOXBdw==",
|
||||
"requires": {
|
||||
"fastfile": "0.0.1",
|
||||
"ffjavascript": "0.1.0"
|
||||
"fastfile": "0.0.7",
|
||||
"ffjavascript": "0.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"fastfile": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.1.tgz",
|
||||
"integrity": "sha512-Fk8PWafGWGEUw7oPq/dJen92ASxknCEy4ZC8n4VEvSwCp/jcReyEmVoWsRIWTf+IvAp2MzvFi54vOPeK2LQZtQ=="
|
||||
},
|
||||
"ffjavascript": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.1.0.tgz",
|
||||
"integrity": "sha512-dmKlUasSfvUcxBm8nCSKl2x7EFJsXA7OVP8XLFA03T2+6mAc3IiVLC2ambEVOcMOhyhl0vJfVZjM9f9d38D1rw==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.48"
|
||||
}
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.7.tgz",
|
||||
"integrity": "sha512-Zk7sdqsV6DsN/rhjULDfCCowPiMDsziTMFicdkrKN80yybr/6YFf9H91ELXN85dVEf6EYkVR5EHkZNc0dMqZKA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1472,6 +1471,15 @@
|
||||
"big-integer": "^1.6.48"
|
||||
}
|
||||
},
|
||||
"wasmcurves": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.4.tgz",
|
||||
"integrity": "sha512-c/Tob+F/7jJhep1b2qtj54r4nkGaRifNbQ1OJx8cBBFH1RlHbWIbISHWONClOxiVwy/JZOpbN4SgvSX/4lF80A==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.42",
|
||||
"blakejs": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
@@ -1492,6 +1500,11 @@
|
||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||
"dev": true
|
||||
},
|
||||
"worker-threads": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/worker-threads/-/worker-threads-1.0.0.tgz",
|
||||
"integrity": "sha512-vK6Hhvph8oLxocEJIlc3YfGAZhm210uGzjZsXSu+JYLAQ/s/w4Tqgl60JrdH58hW8NSGP4m3bp8a92qPXgX05w=="
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "circom",
|
||||
"version": "0.5.13",
|
||||
"version": "0.5.16",
|
||||
"description": "Language to generate logic circuits",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
@@ -31,12 +31,12 @@
|
||||
"dependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"circom_runtime": "0.0.6",
|
||||
"fastfile": "0.0.2",
|
||||
"fastfile": "0.0.8",
|
||||
"ffiasm": "0.0.2",
|
||||
"ffjavascript": "0.1.2",
|
||||
"ffjavascript": "0.2.4",
|
||||
"ffwasm": "0.0.7",
|
||||
"fnv-plus": "^1.3.1",
|
||||
"r1csfile": "0.0.5",
|
||||
"r1csfile": "0.0.14",
|
||||
"tmp-promise": "^2.0.2",
|
||||
"wasmbuilder": "0.0.10"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const SUBARRAY_SIZE = 0x10000;
|
||||
const SUBARRAY_SIZE = 0x40000;
|
||||
|
||||
const BigArrayHandler = {
|
||||
get: function(obj, prop) {
|
||||
@@ -19,7 +19,7 @@ const BigArrayHandler = {
|
||||
class _BigArray {
|
||||
constructor (initSize) {
|
||||
this.length = initSize || 0;
|
||||
this.arr = [];
|
||||
this.arr = new Array(SUBARRAY_SIZE);
|
||||
|
||||
for (let i=0; i<initSize; i+=SUBARRAY_SIZE) {
|
||||
this.arr[i/SUBARRAY_SIZE] = new Array(Math.min(SUBARRAY_SIZE, initSize - i));
|
||||
@@ -39,13 +39,26 @@ class _BigArray {
|
||||
idx = parseInt(idx);
|
||||
const idx1 = Math.floor(idx / SUBARRAY_SIZE);
|
||||
if (!this.arr[idx1]) {
|
||||
this.arr[idx1] = [];
|
||||
this.arr[idx1] = new Array(SUBARRAY_SIZE);
|
||||
}
|
||||
const idx2 = idx % SUBARRAY_SIZE;
|
||||
this.arr[idx1][idx2] = value;
|
||||
if (idx >= this.length) this.length = idx+1;
|
||||
return true;
|
||||
}
|
||||
getKeys() {
|
||||
const newA = new BigArray();
|
||||
for (let i=0; i<this.arr.length; i++) {
|
||||
if (this.arr[i]) {
|
||||
for (let j=0; j<this.arr[i].length; j++) {
|
||||
if (typeof this.arr[i][j] !== "undefined") {
|
||||
newA.push(i*SUBARRAY_SIZE+j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return newA;
|
||||
}
|
||||
}
|
||||
|
||||
class BigArray {
|
||||
|
||||
261
src/compiler.js
261
src/compiler.js
@@ -44,9 +44,12 @@ async function compile(srcFile, options) {
|
||||
ctx.mainComponent = options.mainComponent || "main";
|
||||
ctx.newThreadTemplates = options.newThreadTemplates;
|
||||
|
||||
if (ctx.verbose) console.time("Construction Phase");
|
||||
constructionPhase(ctx, srcFile);
|
||||
if (ctx.verbose) console.timeEnd("Construction Phase");
|
||||
|
||||
if (ctx.verbose) console.log("NConstraints Before: "+ctx.constraints.length);
|
||||
if (ctx.verbose) console.log("NSignals Before: "+ctx.signals.length);
|
||||
|
||||
if (ctx.error) {
|
||||
throw(ctx.error);
|
||||
@@ -57,25 +60,38 @@ async function compile(srcFile, options) {
|
||||
}
|
||||
|
||||
if (ctx.verbose) console.log("Classify Signals");
|
||||
if (ctx.verbose) console.time("Classify Signals");
|
||||
classifySignals(ctx);
|
||||
if (ctx.verbose) console.timeEnd("Classify Signals");
|
||||
|
||||
if (ctx.verbose) console.log("Reduce Constants");
|
||||
if (ctx.verbose) console.time("Reduce Constants");
|
||||
reduceConstants(ctx);
|
||||
if (ctx.verbose) console.timeEnd("Reduce Constants");
|
||||
|
||||
if (options.reduceConstraints) {
|
||||
|
||||
if (ctx.verbose) console.log("Reduce Constraints");
|
||||
// Repeat while reductions are performed
|
||||
/*
|
||||
let oldNConstrains = -1;
|
||||
while (ctx.constraints.length != oldNConstrains) {
|
||||
if (ctx.verbose) console.log("Reducing constraints: "+ctx.constraints.length);
|
||||
oldNConstrains = ctx.constraints.length;
|
||||
reduceConstrains(ctx);
|
||||
}
|
||||
*/
|
||||
if (ctx.verbose) console.time("Reduce Constraints");
|
||||
await reduceConstrains(ctx);
|
||||
if (ctx.verbose) console.timeEnd("Reduce Constraints");
|
||||
|
||||
}
|
||||
|
||||
if (ctx.verbose) console.log("NConstraints After: "+ctx.constraints.length);
|
||||
|
||||
if (ctx.verbose) console.time("Generate Witness Names");
|
||||
generateWitnessNames(ctx);
|
||||
if (ctx.verbose) console.timeEnd("Generate Witness Names");
|
||||
|
||||
if (ctx.error) {
|
||||
throw(ctx.error);
|
||||
@@ -83,16 +99,19 @@ async function compile(srcFile, options) {
|
||||
|
||||
if (options.cSourceWriteStream) {
|
||||
if (ctx.verbose) console.log("Generating c...");
|
||||
if (ctx.verbose) console.time("Generate C");
|
||||
ctx.builder = new BuilderC(options.prime);
|
||||
build(ctx);
|
||||
const rdStream = ctx.builder.build();
|
||||
rdStream.pipe(options.cSourceWriteStream);
|
||||
if (ctx.verbose) console.timeEnd("Generate C");
|
||||
|
||||
// await new Promise(fulfill => options.cSourceWriteStream.on("finish", fulfill));
|
||||
}
|
||||
|
||||
if ((options.wasmWriteStream)||(options.watWriteStream)) {
|
||||
if (ctx.verbose) console.log("Generating wasm...");
|
||||
if (ctx.verbose) console.time("Generating wasm");
|
||||
ctx.builder = new BuilderWasm(options.prime);
|
||||
build(ctx);
|
||||
if (options.wasmWriteStream) {
|
||||
@@ -103,6 +122,7 @@ async function compile(srcFile, options) {
|
||||
const rdStream = ctx.builder.build("wat");
|
||||
rdStream.pipe(options.watWriteStream);
|
||||
}
|
||||
if (ctx.verbose) console.timeEnd("Generate wasm");
|
||||
|
||||
// await new Promise(fulfill => options.wasmWriteStream.on("finish", fulfill));
|
||||
}
|
||||
@@ -111,12 +131,18 @@ async function compile(srcFile, options) {
|
||||
if (ctx.error) throw(ctx.error);
|
||||
|
||||
if (options.r1csFileName) {
|
||||
if (ctx.verbose) console.log("Generating r1cs...");
|
||||
if (ctx.verbose) console.time("Generating r1cs");
|
||||
await buildR1cs(ctx, options.r1csFileName);
|
||||
if (ctx.verbose) console.timeEnd("Generating r1cs");
|
||||
}
|
||||
|
||||
if (options.symWriteStream) {
|
||||
if (ctx.verbose) console.log("Generating syms...");
|
||||
if (ctx.verbose) console.time("Generating syms");
|
||||
const rdStream = buildSyms(ctx);
|
||||
rdStream.pipe(options.symWriteStream);
|
||||
if (ctx.verbose) console.timeEnd("Generating syms");
|
||||
|
||||
// await new Promise(fulfill => options.symWriteStream.on("finish", fulfill));
|
||||
}
|
||||
@@ -148,6 +174,7 @@ function classifySignals(ctx) {
|
||||
|
||||
// First classify the signals
|
||||
for (let s=0; s<ctx.signals.length; s++) {
|
||||
if ((ctx.verbose)&&(s%100000 == 0)) console.log(`classify signals: ${s}/${ctx.signals.length}`);
|
||||
const signal = ctx.signals[s];
|
||||
let tAll = ctx.stINTERNAL;
|
||||
let lSignal = signal;
|
||||
@@ -251,7 +278,239 @@ function reduceConstants(ctx) {
|
||||
ctx.constraints = newConstraints;
|
||||
}
|
||||
|
||||
function reduceConstrains(ctx) {
|
||||
async function reduceConstrains(ctx) {
|
||||
const sig2constraint = new BigArray();
|
||||
let removedSignals = new BigArray();
|
||||
let nRemoved;
|
||||
let lIdx;
|
||||
|
||||
|
||||
let possibleConstraints = new BigArray(ctx.constraints.length);
|
||||
let nextPossibleConstraints;
|
||||
for (let i=0; i<ctx.constraints.length; i++) {
|
||||
if ((ctx.verbose)&&(i%100000 == 0)) console.log(`indexing constraints: ${i}/${ctx.constraints.length}`);
|
||||
|
||||
const insertedSig = { 0: true}; // Do not insert one.
|
||||
const c = ctx.constraints[i];
|
||||
for (let s in c.a.coefs) {
|
||||
if (!insertedSig[s]) {
|
||||
if (!sig2constraint[s]) sig2constraint[s] = [];
|
||||
sig2constraint[s].push(i);
|
||||
insertedSig[s] = true;
|
||||
}
|
||||
}
|
||||
for (let s in c.b.coefs) {
|
||||
if (!insertedSig[s]) {
|
||||
if (!sig2constraint[s]) sig2constraint[s] = [];
|
||||
sig2constraint[s].push(i);
|
||||
insertedSig[s] = true;
|
||||
}
|
||||
}
|
||||
for (let s in c.c.coefs) {
|
||||
if (!insertedSig[s]) {
|
||||
if (!sig2constraint[s]) sig2constraint[s] = [];
|
||||
sig2constraint[s].push(i);
|
||||
insertedSig[s] = true;
|
||||
}
|
||||
}
|
||||
possibleConstraints[i] = i;
|
||||
}
|
||||
|
||||
while (possibleConstraints.length >0) {
|
||||
nextPossibleConstraints = new BigArray();
|
||||
removedSignals = new BigArray();
|
||||
nRemoved = 0;
|
||||
lIdx = new BigArray();
|
||||
for (let i=0;i<possibleConstraints.length;i++) {
|
||||
if ((ctx.verbose)&&(i%10000 == 0)) {
|
||||
await Promise.resolve();
|
||||
console.log(`reducing constraints: ${i}/${possibleConstraints.length} reduced: ${nRemoved}`);
|
||||
}
|
||||
const c = ctx.constraints[possibleConstraints[i]];
|
||||
if (!c) continue;
|
||||
|
||||
// Swap a and b if b has more variables.
|
||||
if (Object.keys(c.b).length > Object.keys(c.a).length) {
|
||||
const aux = c.a;
|
||||
c.a=c.b;
|
||||
c.b=aux;
|
||||
}
|
||||
|
||||
// Mov to C if possible.
|
||||
if (isConstant(c.a)) {
|
||||
const ct = {t: "N", v: c.a.coefs[sONE]};
|
||||
c.c = ctx.lc.add(ctx.lc.mul(c.b, ct), c.c);
|
||||
c.a = { t: "LC", coefs: {} };
|
||||
c.b = { t: "LC", coefs: {} };
|
||||
}
|
||||
if (isConstant(c.b)) {
|
||||
const ct = {t: "N", v: c.b.coefs[sONE]};
|
||||
c.c = ctx.lc.add(ctx.lc.mul(c.a, ct), c.c);
|
||||
c.a = { t: "LC", coefs: {} };
|
||||
c.b = { t: "LC", coefs: {} };
|
||||
}
|
||||
|
||||
if (ctx.lc.isZero(c.a) || ctx.lc.isZero(c.b)) {
|
||||
const freeC = substituteRemoved(c.c);
|
||||
const isolatedSignal = getFirstInternalSignal(ctx, freeC);
|
||||
if (isolatedSignal) {
|
||||
// console.log(isolatedSignal);
|
||||
// console.log(freeC);
|
||||
removedSignals[isolatedSignal] = isolateSignal(freeC, isolatedSignal);
|
||||
if (lIdx[isolatedSignal]) {
|
||||
lIdx[isolatedSignal].forEach( (s) => {
|
||||
removedSignals[s] = substitute(removedSignals[s], isolatedSignal, removedSignals[isolatedSignal]);
|
||||
});
|
||||
}
|
||||
|
||||
addTolIdx(removedSignals[isolatedSignal], isolatedSignal);
|
||||
ctx.constraints[possibleConstraints[i]] = null;
|
||||
nRemoved ++;
|
||||
|
||||
sig2constraint[isolatedSignal].forEach( (s) => {
|
||||
nextPossibleConstraints[s] = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextPossibleConstraints = nextPossibleConstraints.getKeys();
|
||||
|
||||
for (let i=0; i<nextPossibleConstraints.length;i++) {
|
||||
if ((ctx.verbose)&&(i%10000 == 0)) {
|
||||
await Promise.resolve();
|
||||
console.log(`substituting constraints: ${i}/${nextPossibleConstraints.length}`);
|
||||
}
|
||||
const c = ctx.constraints[nextPossibleConstraints[i]];
|
||||
if (c) {
|
||||
const nc = {
|
||||
a: substituteRemoved(c.a),
|
||||
b: substituteRemoved(c.b),
|
||||
c: substituteRemoved(c.c)
|
||||
};
|
||||
if (ctx.lc.isZero(nc)) {
|
||||
delete ctx.constraints[nextPossibleConstraints[i]];
|
||||
} else {
|
||||
ctx.constraints[nextPossibleConstraints[i]] = nc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const removedSignalsList = removedSignals.getKeys;
|
||||
|
||||
for (let i=0; i<removedSignalsList.length; i++) {
|
||||
if ((ctx.verbose )&&(i%100000 == 0)) console.log(`removing signals: ${i}/${removedSignalsList.length}`);
|
||||
const s = removedSignalsList[i];
|
||||
|
||||
let lSignal = ctx.signals[s];
|
||||
while (lSignal.e>=0) {
|
||||
lSignal = ctx.signals[lSignal.e];
|
||||
}
|
||||
|
||||
lSignal.c = ctx.stDISCARDED;
|
||||
}
|
||||
|
||||
possibleConstraints = nextPossibleConstraints;
|
||||
}
|
||||
|
||||
let o=0;
|
||||
for (let i=0; i<ctx.constraints.length;i++) {
|
||||
if ((ctx.verbose)&&(i%100000 == 0)) console.log(`reordering constraints: ${i}/${ctx.constraints.length}`);
|
||||
if (ctx.constraints[i]) {
|
||||
if (!ctx.lc.isZero(ctx.constraints[i])) {
|
||||
ctx.constraints[o] = ctx.constraints[i];
|
||||
o++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.constraints.length = o;
|
||||
|
||||
function getFirstInternalSignal(ctx, l) {
|
||||
for (let k in l.coefs) {
|
||||
k = Number(k);
|
||||
const signal = ctx.signals[k];
|
||||
if ((signal.c == ctx.stINTERNAL)&&(!ctx.F.isZero(l.coefs[k])) &&(!removedSignals[k])) return k;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function isolateSignal(lc, s) {
|
||||
const eq = {
|
||||
t: "LC",
|
||||
coefs: {}
|
||||
};
|
||||
const invCoef = ctx.F.inv(lc.coefs[s]);
|
||||
for (const k in lc.coefs) {
|
||||
if (k != s) {
|
||||
const v = ctx.F.mul( ctx.F.neg(lc.coefs[k]), invCoef);
|
||||
if (!ctx.F.isZero(v)) {
|
||||
eq.coefs[k] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return eq;
|
||||
}
|
||||
|
||||
function substituteRemoved(lc) {
|
||||
const newLc = ctx.lc._clone(lc);
|
||||
for (let k in lc.coefs) {
|
||||
if (removedSignals[k]) {
|
||||
delete newLc.coefs[k];
|
||||
for (let k2 in removedSignals[k].coefs) {
|
||||
const newP = ctx.F.mul(removedSignals[k].coefs[k2], lc.coefs[k]);
|
||||
if (!ctx.F.isZero(newP)) {
|
||||
if (newLc.coefs[k2]) {
|
||||
newLc.coefs[k2] = ctx.F.add(newLc.coefs[k2], newP);
|
||||
if (ctx.F.isZero(newLc.coefs[k2])) delete newLc.coefs[k2];
|
||||
} else {
|
||||
newLc.coefs[k2] = newP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return newLc;
|
||||
}
|
||||
|
||||
function substitute(lc, s, eq) {
|
||||
if (!lc.coefs[s]) return lc;
|
||||
const newLc = ctx.lc._clone(lc);
|
||||
delete newLc.coefs[s];
|
||||
for (let k2 in eq.coefs) {
|
||||
const newP = ctx.F.mul(eq.coefs[k2], lc.coefs[s]);
|
||||
if (!ctx.F.isZero(newP)) {
|
||||
if (newLc.coefs[k2]) {
|
||||
newLc.coefs[k2] = ctx.F.add(newLc.coefs[k2], newP);
|
||||
if (ctx.F.isZero(newLc.coefs[k2])) delete newLc.coefs[k2];
|
||||
} else {
|
||||
newLc.coefs[k2] = newP;
|
||||
}
|
||||
}
|
||||
}
|
||||
return newLc;
|
||||
}
|
||||
|
||||
function isConstant(l) {
|
||||
for (let k in l.coefs) {
|
||||
if ((k != sONE) && (!ctx.F.isZero(l.coefs[k]))) return false;
|
||||
}
|
||||
if (!l.coefs[sONE] || ctx.F.isZero(l.coefs[sONE])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function addTolIdx(lc, newS) {
|
||||
for (let s in lc.coefs) {
|
||||
if (!lIdx[s]) lIdx[s] = [];
|
||||
lIdx[s].push(newS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function reduceConstrains_old(ctx) {
|
||||
indexVariables();
|
||||
let possibleConstraints = ctx.constraints;
|
||||
let ii=0;
|
||||
|
||||
@@ -123,6 +123,7 @@ class LCAlgebra {
|
||||
}
|
||||
|
||||
_signal2lc(a) {
|
||||
const self = this;
|
||||
if (a.t == "S") {
|
||||
const lc = {
|
||||
t: "LC",
|
||||
|
||||
@@ -4,11 +4,14 @@ const assert = require("assert");
|
||||
|
||||
module.exports.buildR1cs = buildR1cs;
|
||||
|
||||
|
||||
async function buildR1cs(ctx, fileName) {
|
||||
|
||||
const fd = await fastFile.createOverride(fileName);
|
||||
|
||||
|
||||
const buffBigInt = new Uint8Array(ctx.F.n8);
|
||||
|
||||
const type = "r1cs";
|
||||
const buff = new Uint8Array(4);
|
||||
for (let i=0; i<4; i++) buff[i] = type.charCodeAt(i);
|
||||
@@ -79,7 +82,7 @@ async function buildR1cs(ctx, fileName) {
|
||||
}
|
||||
for (let i=0; i<arr.length; i++) {
|
||||
await fd.writeULE64(arr[i]);
|
||||
if ((ctx.verbose)&&(i%100000)) console.log("writing wire2label map: ", i);
|
||||
if ((ctx.verbose)&&(i%100000 == 0)) console.log(`writing wire2label map: ${i}/${arr.length}`);
|
||||
}
|
||||
|
||||
const mapSize = fd.pos - pMapSize - 8;
|
||||
@@ -112,12 +115,9 @@ async function buildR1cs(ctx, fileName) {
|
||||
|
||||
async function writeBigInt(n, pos) {
|
||||
|
||||
const s = n.toString(16);
|
||||
const b = Buffer.from(s.padStart(n8*2, "0"), "hex");
|
||||
const buff = new Uint8Array(b.length);
|
||||
for (let i=0; i<b.length; i++) buff[i] = b[b.length-1-i];
|
||||
ctx.F.toRprLE(buffBigInt, 0, n);
|
||||
|
||||
await fd.write(buff, pos);
|
||||
await fd.write(buffBigInt, pos);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user