mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-07 11:16:42 +01:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
349a39dc95 | ||
|
|
0a2aee9932 | ||
|
|
bad8fad3d0 | ||
|
|
0a707648fc | ||
|
|
263dc73906 | ||
|
|
8e730d93a4 | ||
|
|
bbe10438e0 | ||
|
|
c2cef8d80c | ||
|
|
2200408986 | ||
|
|
5f13d37fdc | ||
|
|
3b46b74d4a | ||
|
|
aa2d768465 | ||
|
|
f02ceb2508 | ||
|
|
d014d67032 | ||
|
|
2e1b35a94d |
3
cli.js
3
cli.js
@@ -24,6 +24,7 @@
|
|||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
const stringifyBigInts = require("ffjavascript").utils.stringifyBigInts;
|
||||||
const fastFile = require("fastfile");
|
const fastFile = require("fastfile");
|
||||||
|
|
||||||
const compiler = require("./src/compiler");
|
const compiler = require("./src/compiler");
|
||||||
@@ -153,7 +154,7 @@ run().then(()=> {
|
|||||||
if (argv.verbose) console.log(err.stack);
|
if (argv.verbose) console.log(err.stack);
|
||||||
}
|
}
|
||||||
if (err.ast) {
|
if (err.ast) {
|
||||||
console.error(JSON.stringify(err.ast, null, 1));
|
console.error(JSON.stringify(stringifyBigInts(err.ast), null, 1));
|
||||||
}
|
}
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|||||||
57
package-lock.json
generated
57
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circom",
|
"name": "circom",
|
||||||
"version": "0.5.19",
|
"version": "0.5.26",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -203,11 +203,11 @@
|
|||||||
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
|
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
|
||||||
},
|
},
|
||||||
"circom_runtime": {
|
"circom_runtime": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.5.tgz",
|
||||||
"integrity": "sha512-qh1GsfxXLGAhLBcIQWrFHO/zu6kuXQQL1xC3+P8KRETvynTbBVSb1ul3dCiXyetm7lVNNdhb1/UoOCEZ6yu1RQ==",
|
"integrity": "sha512-BT3d9VCrH/rBRbThDXG731JwezKyskxyE46nACO6Tt/jaorn27LDxFDORdAAjyD0RAoBt+6FpaTp3qlYSx7Pjg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"ffjavascript": "0.2.4",
|
"ffjavascript": "0.2.10",
|
||||||
"fnv-plus": "^1.3.1"
|
"fnv-plus": "^1.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -334,9 +334,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ejs": {
|
"ejs": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz",
|
||||||
"integrity": "sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg==",
|
"integrity": "sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"jake": "^10.6.1"
|
"jake": "^10.6.1"
|
||||||
}
|
}
|
||||||
@@ -566,14 +566,14 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"fastfile": {
|
"fastfile": {
|
||||||
"version": "0.0.12",
|
"version": "0.0.16",
|
||||||
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.12.tgz",
|
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.16.tgz",
|
||||||
"integrity": "sha512-0EZo2y5eW8X0oiDDRvcnufjVxlM96CQL5hvmRQtbRABWlCkH73IHwkzl0qOSdxtchaMr+0TSB7GVqaVEixRr1Q=="
|
"integrity": "sha512-2sX5M4JQWAVmS2GojuRPA759aTOs5PyUEpZHjaecNtWBU9CfRFlTf2aBqFG2PJJnrcrawBBAQ1s0QSO+qQ4Zmg=="
|
||||||
},
|
},
|
||||||
"ffiasm": {
|
"ffiasm": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ffiasm/-/ffiasm-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ffiasm/-/ffiasm-0.1.1.tgz",
|
||||||
"integrity": "sha512-fQI7b6oye7Yw3t28ku9XuhPSwwzKMeqB0pkIaGPrKl9s/ipV90o8J4Ge0s5F0UsH5Mu2wfr3hFQ2sGF+vQk5Sg==",
|
"integrity": "sha512-irMMHiR9JJ7BVBrAhtliUawxVdPYSdyl81taUYJ4C1mJ0iw2ueThE/qtr0J8B83tsIY8HJvh0lg5F+6ClK4xpA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"big-integer": "^1.6.48",
|
"big-integer": "^1.6.48",
|
||||||
"ejs": "^3.0.1",
|
"ejs": "^3.0.1",
|
||||||
@@ -581,13 +581,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ffjavascript": {
|
"ffjavascript": {
|
||||||
"version": "0.2.4",
|
"version": "0.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.10.tgz",
|
||||||
"integrity": "sha512-XFeWcjUDFPavN+DDOxhE8p5MOhZQJc9oO1Sj4ml1pyjqNhS1ujEamcjFyK0cctdnat61i7lvpTYzdtS3RYDC8w==",
|
"integrity": "sha512-GQI6gHYYG5/iD4Kt3VzezzK7fARJzP0zkc82V/+JAdjfeKBXhDSo5rpKFuK3cDcrdW0Fu2emuYNMEAuFqhEQvQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"big-integer": "^1.6.48",
|
"big-integer": "^1.6.48",
|
||||||
"wasmcurves": "0.0.4",
|
"wasmcurves": "0.0.5",
|
||||||
"worker-threads": "^1.0.0"
|
"worker-threads": "^1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"wasmcurves": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.5.tgz",
|
||||||
|
"integrity": "sha512-BmI4GXLjLawGg2YkvHa8zRsnWec+d1uwoxE+Iov8cqOpDL7GA5XO2pk2yuDbXHMzwIug2exnKot3baRZ86R0pA==",
|
||||||
|
"requires": {
|
||||||
|
"big-integer": "^1.6.42",
|
||||||
|
"blakejs": "^1.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ffwasm": {
|
"ffwasm": {
|
||||||
@@ -1163,6 +1174,16 @@
|
|||||||
"version": "0.0.7",
|
"version": "0.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.7.tgz",
|
||||||
"integrity": "sha512-Zk7sdqsV6DsN/rhjULDfCCowPiMDsziTMFicdkrKN80yybr/6YFf9H91ELXN85dVEf6EYkVR5EHkZNc0dMqZKA=="
|
"integrity": "sha512-Zk7sdqsV6DsN/rhjULDfCCowPiMDsziTMFicdkrKN80yybr/6YFf9H91ELXN85dVEf6EYkVR5EHkZNc0dMqZKA=="
|
||||||
|
},
|
||||||
|
"ffjavascript": {
|
||||||
|
"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",
|
||||||
|
"wasmcurves": "0.0.4",
|
||||||
|
"worker-threads": "^1.0.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circom",
|
"name": "circom",
|
||||||
"version": "0.5.19",
|
"version": "0.5.26",
|
||||||
"description": "Language to generate logic circuits",
|
"description": "Language to generate logic circuits",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -30,10 +30,10 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"circom_runtime": "0.1.2",
|
"circom_runtime": "0.1.5",
|
||||||
"fastfile": "0.0.12",
|
"fastfile": "0.0.16",
|
||||||
"ffiasm": "0.1.0",
|
"ffiasm": "0.1.1",
|
||||||
"ffjavascript": "0.2.4",
|
"ffjavascript": "0.2.10",
|
||||||
"ffwasm": "0.0.7",
|
"ffwasm": "0.0.7",
|
||||||
"fnv-plus": "^1.3.1",
|
"fnv-plus": "^1.3.1",
|
||||||
"r1csfile": "0.0.14",
|
"r1csfile": "0.0.14",
|
||||||
|
|||||||
@@ -95,6 +95,10 @@ class CodeBuilderC {
|
|||||||
this.ops.push({op: "CHECKCONSTRAINT", a, b, strErr});
|
this.ops.push({op: "CHECKCONSTRAINT", a, b, strErr});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkAssert(a, strErr) {
|
||||||
|
this.ops.push({op: "CHECKASSERT", a, strErr});
|
||||||
|
}
|
||||||
|
|
||||||
log(val) {
|
log(val) {
|
||||||
this.ops.push({op: "LOG", val});
|
this.ops.push({op: "LOG", val});
|
||||||
}
|
}
|
||||||
@@ -215,6 +219,8 @@ class CodeBuilderC {
|
|||||||
code.push(`${o.fnName}(ctx, ${o.retLabel}, ${o.params.join(",")});`);
|
code.push(`${o.fnName}(ctx, ${o.retLabel}, ${o.params.join(",")});`);
|
||||||
} else if (o.op == "CHECKCONSTRAINT") {
|
} else if (o.op == "CHECKCONSTRAINT") {
|
||||||
code.push(`ctx->checkConstraint(__cIdx, ${ref2src(o.a)}, ${ref2src(o.b)}, "${o.strErr}");`);
|
code.push(`ctx->checkConstraint(__cIdx, ${ref2src(o.a)}, ${ref2src(o.b)}, "${o.strErr}");`);
|
||||||
|
} else if (o.op == "CHECKASSERT") {
|
||||||
|
code.push(`ctx->checkAssert(__cIdx, ${ref2src(o.a)}, "${o.strErr}");`);
|
||||||
} else if (o.op == "LOG") {
|
} else if (o.op == "LOG") {
|
||||||
code.push(`ctx->log(${ref2src(o.val)});`);
|
code.push(`ctx->log(${ref2src(o.val)});`);
|
||||||
}
|
}
|
||||||
@@ -356,7 +362,6 @@ class BuilderC {
|
|||||||
|
|
||||||
this.sizePointers = {};
|
this.sizePointers = {};
|
||||||
this.hashMapPointers = {};
|
this.hashMapPointers = {};
|
||||||
this.cetPointers = {};
|
|
||||||
this.functionIdx = {};
|
this.functionIdx = {};
|
||||||
this.nCets = 0;
|
this.nCets = 0;
|
||||||
}
|
}
|
||||||
@@ -370,11 +375,11 @@ class BuilderC {
|
|||||||
this.hashMaps[name] = hm;
|
this.hashMaps[name] = hm;
|
||||||
}
|
}
|
||||||
|
|
||||||
addComponentEntriesTable(name, cet) {
|
addComponentEntriesTable(name, cet, idComponent) {
|
||||||
this.componentEntriesTables.push({
|
this.componentEntriesTables[idComponent] = {
|
||||||
name: name,
|
name: name,
|
||||||
cet: cet
|
cet: cet
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
addSizes(name, accSizes) {
|
addSizes(name, accSizes) {
|
||||||
@@ -462,10 +467,9 @@ class BuilderC {
|
|||||||
this.pCets = fdData.pos;
|
this.pCets = fdData.pos;
|
||||||
for (let i=0; i< this.componentEntriesTables.length; i++) {
|
for (let i=0; i< this.componentEntriesTables.length; i++) {
|
||||||
if ((this.verbose)&&(i%100000 ==0)) console.log(`_buildComponentEntriesTables ${i}/${this.componentEntriesTables.length}`);
|
if ((this.verbose)&&(i%100000 ==0)) console.log(`_buildComponentEntriesTables ${i}/${this.componentEntriesTables.length}`);
|
||||||
const cetName = this.componentEntriesTables[i].name;
|
|
||||||
const cet = this.componentEntriesTables[i].cet;
|
const cet = this.componentEntriesTables[i].cet;
|
||||||
|
|
||||||
this.cetPointers[cetName] = fdData.pos;
|
this.components[i].entryTablePointer = fdData.pos;
|
||||||
const buff = new Uint8Array(16*cet.length);
|
const buff = new Uint8Array(16*cet.length);
|
||||||
const buffV = new DataView(buff.buffer);
|
const buffV = new DataView(buff.buffer);
|
||||||
|
|
||||||
@@ -612,7 +616,7 @@ class BuilderC {
|
|||||||
const c = this.components[i];
|
const c = this.components[i];
|
||||||
|
|
||||||
utils.setUint64(buffV, 0, this.hashMapPointers[c.hashMapName], true);
|
utils.setUint64(buffV, 0, this.hashMapPointers[c.hashMapName], true);
|
||||||
utils.setUint64(buffV, 8, this.cetPointers[c.entryTableName], true);
|
utils.setUint64(buffV, 8, c.entryTablePointer, true);
|
||||||
utils.setUint64(buffV, 16, this.functionIdx[c.functionName], true);
|
utils.setUint64(buffV, 16, this.functionIdx[c.functionName], true);
|
||||||
buffV.setUint32(24, c.nInSignals, true);
|
buffV.setUint32(24, c.nInSignals, true);
|
||||||
buffV.setUint32(28, c.newThread ? 1 : 0, true);
|
buffV.setUint32(28, c.newThread ? 1 : 0, true);
|
||||||
|
|||||||
@@ -384,9 +384,9 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
"error",
|
"error",
|
||||||
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.code),
|
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.code),
|
||||||
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.pointer),
|
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.pointer),
|
||||||
c.i32_const(0),
|
c.getLocal("cIdx"),
|
||||||
c.i32_const(0),
|
c.getLocal("component"),
|
||||||
c.i32_const(0),
|
c.getLocal("signal"),
|
||||||
c.i32_const(0)
|
c.i32_const(0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -619,6 +619,35 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildCheckAssert() {
|
||||||
|
const f = module.addFunction("checkAssert");
|
||||||
|
f.addParam("cIdx", "i32");
|
||||||
|
f.addParam("pA", "i32");
|
||||||
|
f.addParam("pStr", "i32");
|
||||||
|
|
||||||
|
const c = f.getCodeBuilder();
|
||||||
|
|
||||||
|
f.addCode(ifSanityCheck(c,
|
||||||
|
c.if (
|
||||||
|
c.i32_eqz(
|
||||||
|
c.call(
|
||||||
|
"Fr_isTrue",
|
||||||
|
c.getLocal("pA"),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
c.call(
|
||||||
|
"error",
|
||||||
|
c.i32_const(errs.ASSERT_DOES_NOT_MATCH.code),
|
||||||
|
c.i32_const(errs.ASSERT_DOES_NOT_MATCH.pointer),
|
||||||
|
c.getLocal("cIdx"),
|
||||||
|
c.getLocal("pA"),
|
||||||
|
c.getLocal("pStr"),
|
||||||
|
c.i32_const(0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
function buildGetNVars() {
|
function buildGetNVars() {
|
||||||
const f = module.addFunction("getNVars");
|
const f = module.addFunction("getNVars");
|
||||||
f.setReturnType("i32");
|
f.setReturnType("i32");
|
||||||
@@ -823,6 +852,7 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
buildComponentFinished();
|
buildComponentFinished();
|
||||||
|
|
||||||
buildCheckConstraint();
|
buildCheckConstraint();
|
||||||
|
buildCheckAssert();
|
||||||
|
|
||||||
buildGetNVars();
|
buildGetNVars();
|
||||||
buildGetFrLen();
|
buildGetFrLen();
|
||||||
|
|||||||
@@ -98,6 +98,9 @@ class CodeBuilderWasm {
|
|||||||
this.ops.push({op: "CHECKCONSTRAINT", a, b, strErr});
|
this.ops.push({op: "CHECKCONSTRAINT", a, b, strErr});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkAssert(a, strErr) {
|
||||||
|
this.ops.push({op: "CHECKASSERT", a, strErr});
|
||||||
|
}
|
||||||
|
|
||||||
concat(cb) {
|
concat(cb) {
|
||||||
this.ops.push(...cb.ops);
|
this.ops.push(...cb.ops);
|
||||||
@@ -332,6 +335,15 @@ class CodeBuilderWasm {
|
|||||||
c.i32_const(this.fnBuilder.builder.module.allocString(o.strErr))
|
c.i32_const(this.fnBuilder.builder.module.allocString(o.strErr))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
} else if (o.op == "CHECKASSERT") {
|
||||||
|
code.push(
|
||||||
|
c.call(
|
||||||
|
"checkAssert",
|
||||||
|
c.getLocal("cIdx"),
|
||||||
|
this.fnBuilder._deRefFr(c, o.a),
|
||||||
|
c.i32_const(this.fnBuilder.builder.module.allocString(o.strErr))
|
||||||
|
)
|
||||||
|
);
|
||||||
} else if (o.op == "LOG") {
|
} else if (o.op == "LOG") {
|
||||||
code.push(
|
code.push(
|
||||||
c.call(
|
c.call(
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ module.exports = {
|
|||||||
SIGNAL_ASSIGNED_TWICE: {code: 6, str: "Signal assigned twice"},
|
SIGNAL_ASSIGNED_TWICE: {code: 6, str: "Signal assigned twice"},
|
||||||
CONSTRAIN_DOES_NOT_MATCH: {code: 7, str: "Constraint doesn't match"},
|
CONSTRAIN_DOES_NOT_MATCH: {code: 7, str: "Constraint doesn't match"},
|
||||||
MAPISINPUT_DONT_MATCH: {code: 8, str: "MapIsInput don't match"},
|
MAPISINPUT_DONT_MATCH: {code: 8, str: "MapIsInput don't match"},
|
||||||
|
ASSERT_DOES_NOT_MATCH: {code: 9, str: "Assert not satisfied"},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ function buildEntryTables(ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.builder.addComponentEntriesTable(componentEntriesTableName, componentEntriesTable);
|
ctx.builder.addComponentEntriesTable(componentEntriesTableName, componentEntriesTable, i);
|
||||||
|
|
||||||
ctx.components[i].htName = htName;
|
ctx.components[i].htName = htName;
|
||||||
ctx.components[i].etName = componentEntriesTableName;
|
ctx.components[i].etName = componentEntriesTableName;
|
||||||
|
|||||||
378
src/compiler.js
378
src/compiler.js
@@ -318,30 +318,34 @@ async function reduceConstrains(ctx) {
|
|||||||
const c = ctx.constraints[i];
|
const c = ctx.constraints[i];
|
||||||
for (let s in c.a.coefs) {
|
for (let s in c.a.coefs) {
|
||||||
if (!insertedSig[s]) {
|
if (!insertedSig[s]) {
|
||||||
if (!sig2constraint[s]) sig2constraint[s] = [];
|
if (!sig2constraint[s]) sig2constraint[s] = {};
|
||||||
sig2constraint[s].push(i);
|
sig2constraint[s][i] = true;
|
||||||
insertedSig[s] = true;
|
insertedSig[s] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let s in c.b.coefs) {
|
for (let s in c.b.coefs) {
|
||||||
if (!insertedSig[s]) {
|
if (!insertedSig[s]) {
|
||||||
if (!sig2constraint[s]) sig2constraint[s] = [];
|
if (!sig2constraint[s]) sig2constraint[s] = {};
|
||||||
sig2constraint[s].push(i);
|
sig2constraint[s][i] = true;
|
||||||
insertedSig[s] = true;
|
insertedSig[s] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let s in c.c.coefs) {
|
for (let s in c.c.coefs) {
|
||||||
if (!insertedSig[s]) {
|
if (!insertedSig[s]) {
|
||||||
if (!sig2constraint[s]) sig2constraint[s] = [];
|
if (!sig2constraint[s]) sig2constraint[s] = {};
|
||||||
sig2constraint[s].push(i);
|
sig2constraint[s][i] = true;
|
||||||
insertedSig[s] = true;
|
insertedSig[s] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
possibleConstraints[i] = i;
|
possibleConstraints[i] = ctx.constraints.length - i -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (possibleConstraints.length >0) {
|
while (possibleConstraints.length >0) {
|
||||||
|
if (possibleConstraints.length>1<<20) {
|
||||||
nextPossibleConstraints = new BigArray();
|
nextPossibleConstraints = new BigArray();
|
||||||
|
} else {
|
||||||
|
nextPossibleConstraints = {};
|
||||||
|
}
|
||||||
removedSignals = new BigArray();
|
removedSignals = new BigArray();
|
||||||
nRemoved = 0;
|
nRemoved = 0;
|
||||||
lIdx = new BigArray();
|
lIdx = new BigArray();
|
||||||
@@ -378,27 +382,37 @@ async function reduceConstrains(ctx) {
|
|||||||
const freeC = substituteRemoved(c.c);
|
const freeC = substituteRemoved(c.c);
|
||||||
const isolatedSignal = getFirstInternalSignal(ctx, freeC);
|
const isolatedSignal = getFirstInternalSignal(ctx, freeC);
|
||||||
if (isolatedSignal) {
|
if (isolatedSignal) {
|
||||||
// console.log(isolatedSignal);
|
|
||||||
// console.log(freeC);
|
|
||||||
removedSignals[isolatedSignal] = isolateSignal(freeC, isolatedSignal);
|
removedSignals[isolatedSignal] = isolateSignal(freeC, isolatedSignal);
|
||||||
if (lIdx[isolatedSignal]) {
|
if (lIdx[isolatedSignal]) {
|
||||||
lIdx[isolatedSignal].forEach( (s) => {
|
const sigs = Object.keys(lIdx[isolatedSignal]);
|
||||||
|
|
||||||
|
for (let k=0; k<sigs.length; k++) {
|
||||||
|
const s = sigs[k];
|
||||||
|
const oldLC = removedSignals[s];
|
||||||
removedSignals[s] = substitute(removedSignals[s], isolatedSignal, removedSignals[isolatedSignal]);
|
removedSignals[s] = substitute(removedSignals[s], isolatedSignal, removedSignals[isolatedSignal]);
|
||||||
});
|
if (oldLC !== removedSignals[s]) addTolIdx(removedSignals[s], s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addTolIdx(removedSignals[isolatedSignal], isolatedSignal);
|
addTolIdx(removedSignals[isolatedSignal], isolatedSignal);
|
||||||
ctx.constraints[possibleConstraints[i]] = null;
|
ctx.constraints[possibleConstraints[i]] = null;
|
||||||
nRemoved ++;
|
nRemoved ++;
|
||||||
|
|
||||||
sig2constraint[isolatedSignal].forEach( (s) => {
|
delete lIdx[isolatedSignal];
|
||||||
nextPossibleConstraints[s] = true;
|
|
||||||
});
|
const cts = Object.keys(sig2constraint[isolatedSignal]);
|
||||||
|
for (let k=0; k<cts.length; k++) {
|
||||||
|
nextPossibleConstraints[cts[k]] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nextPossibleConstraints.getKeys) {
|
||||||
nextPossibleConstraints = nextPossibleConstraints.getKeys();
|
nextPossibleConstraints = nextPossibleConstraints.getKeys();
|
||||||
|
} else {
|
||||||
|
nextPossibleConstraints = Object.keys(nextPossibleConstraints);
|
||||||
|
}
|
||||||
|
|
||||||
for (let i=0; i<nextPossibleConstraints.length;i++) {
|
for (let i=0; i<nextPossibleConstraints.length;i++) {
|
||||||
if ((ctx.verbose)&&(i%10000 == 0)) {
|
if ((ctx.verbose)&&(i%10000 == 0)) {
|
||||||
@@ -408,9 +422,9 @@ async function reduceConstrains(ctx) {
|
|||||||
const c = ctx.constraints[nextPossibleConstraints[i]];
|
const c = ctx.constraints[nextPossibleConstraints[i]];
|
||||||
if (c) {
|
if (c) {
|
||||||
const nc = {
|
const nc = {
|
||||||
a: substituteRemoved(c.a),
|
a: substituteRemoved(c.a, nextPossibleConstraints[i]),
|
||||||
b: substituteRemoved(c.b),
|
b: substituteRemoved(c.b, nextPossibleConstraints[i]),
|
||||||
c: substituteRemoved(c.c)
|
c: substituteRemoved(c.c, nextPossibleConstraints[i])
|
||||||
};
|
};
|
||||||
if (ctx.lc.isZero(nc)) {
|
if (ctx.lc.isZero(nc)) {
|
||||||
delete ctx.constraints[nextPossibleConstraints[i]];
|
delete ctx.constraints[nextPossibleConstraints[i]];
|
||||||
@@ -420,7 +434,7 @@ async function reduceConstrains(ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const removedSignalsList = removedSignals.getKeys;
|
const removedSignalsList = removedSignals.getKeys();
|
||||||
|
|
||||||
for (let i=0; i<removedSignalsList.length; i++) {
|
for (let i=0; i<removedSignalsList.length; i++) {
|
||||||
if ((ctx.verbose )&&(i%100000 == 0)) console.log(`removing signals: ${i}/${removedSignalsList.length}`);
|
if ((ctx.verbose )&&(i%100000 == 0)) console.log(`removing signals: ${i}/${removedSignalsList.length}`);
|
||||||
@@ -434,9 +448,17 @@ async function reduceConstrains(ctx) {
|
|||||||
lSignal.c = ctx.stDISCARDED;
|
lSignal.c = ctx.stDISCARDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
possibleConstraints = new BigArray();
|
||||||
|
// Reverse
|
||||||
|
for (let i=0; i<nextPossibleConstraints.length; i++) {
|
||||||
|
possibleConstraints[i] = nextPossibleConstraints[nextPossibleConstraints.length -1 -i];
|
||||||
|
}
|
||||||
|
*/
|
||||||
possibleConstraints = nextPossibleConstraints;
|
possibleConstraints = nextPossibleConstraints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let o=0;
|
let o=0;
|
||||||
for (let i=0; i<ctx.constraints.length;i++) {
|
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.verbose)&&(i%100000 == 0)) console.log(`reordering constraints: ${i}/${ctx.constraints.length}`);
|
||||||
@@ -476,7 +498,7 @@ async function reduceConstrains(ctx) {
|
|||||||
return eq;
|
return eq;
|
||||||
}
|
}
|
||||||
|
|
||||||
function substituteRemoved(lc) {
|
function substituteRemoved(lc, idxConstraint) {
|
||||||
const newLc = ctx.lc._clone(lc);
|
const newLc = ctx.lc._clone(lc);
|
||||||
for (let k in lc.coefs) {
|
for (let k in lc.coefs) {
|
||||||
if (removedSignals[k]) {
|
if (removedSignals[k]) {
|
||||||
@@ -491,6 +513,10 @@ async function reduceConstrains(ctx) {
|
|||||||
newLc.coefs[k2] = newP;
|
newLc.coefs[k2] = newP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((typeof idxConstraint != "undefined")&&(k2!=0)) {
|
||||||
|
if (!sig2constraint[k2]) sig2constraint[k2] = {};
|
||||||
|
sig2constraint[k2][idxConstraint] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -524,318 +550,16 @@ async function reduceConstrains(ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addTolIdx(lc, newS) {
|
function addTolIdx(lc, newS) {
|
||||||
for (let s in lc.coefs) {
|
const sigs = Object.keys(lc.coefs);
|
||||||
if (!lIdx[s]) lIdx[s] = [];
|
for (let k=0; k<sigs.length; k++) {
|
||||||
lIdx[s].push(newS);
|
const s = sigs[k];
|
||||||
|
if (s) {
|
||||||
|
if (!lIdx[s]) lIdx[s] = {};
|
||||||
|
lIdx[s][newS] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function reduceConstrains_old(ctx) {
|
|
||||||
indexVariables();
|
|
||||||
let possibleConstraints = ctx.constraints;
|
|
||||||
let ii=0;
|
|
||||||
while (possibleConstraints.length>0) {
|
|
||||||
let nextPossibleConstraints = new BigArray();
|
|
||||||
for (let i=0; i<possibleConstraints.length; i++) {
|
|
||||||
ii++;
|
|
||||||
if ((ctx.verbose)&&(ii%10000 == 0)) console.log("reducing constraints: ", i);
|
|
||||||
if (!ctx.constraints[i]) continue;
|
|
||||||
const c = ctx.constraints[i];
|
|
||||||
|
|
||||||
// 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 isolatedSignal = getFirstInternalSignal(ctx, c.c);
|
|
||||||
if (isolatedSignal) {
|
|
||||||
|
|
||||||
let lSignal = ctx.signals[isolatedSignal];
|
|
||||||
while (lSignal.e>=0) {
|
|
||||||
lSignal = ctx.signals[lSignal.e];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const isolatedSignalEquivalence = {
|
|
||||||
t: "LC",
|
|
||||||
coefs: {}
|
|
||||||
};
|
|
||||||
const invCoef = ctx.F.inv(c.c.coefs[isolatedSignal]);
|
|
||||||
for (const s in c.c.coefs) {
|
|
||||||
if (s != isolatedSignal) {
|
|
||||||
const v = ctx.F.mul( ctx.F.neg(c.c.coefs[s]), invCoef);
|
|
||||||
if (!ctx.F.isZero(v)) {
|
|
||||||
isolatedSignalEquivalence.coefs[s] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let j in lSignal.inConstraints) {
|
|
||||||
if ((j!=i)&&(ctx.constraints[j])) {
|
|
||||||
ctx.constraints[j] = ctx.lc.substitute(ctx.constraints[j], isolatedSignal, isolatedSignalEquivalence);
|
|
||||||
linkSignalsConstraint(j);
|
|
||||||
if (j<i) {
|
|
||||||
nextPossibleConstraints.push(j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.constraints[i] = null;
|
|
||||||
|
|
||||||
lSignal.c = ctx.stDISCARDED;
|
|
||||||
} else {
|
|
||||||
if (ctx.lc.isZero(c.c)) ctx.constraints[i] = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
possibleConstraints = nextPossibleConstraints;
|
|
||||||
}
|
|
||||||
unindexVariables();
|
|
||||||
|
|
||||||
// Pack the constraints
|
|
||||||
let o = 0;
|
|
||||||
for (let i=0; i<ctx.constraints.length; i++) {
|
|
||||||
if (ctx.constraints[i]) {
|
|
||||||
if (o != i) {
|
|
||||||
ctx.constraints[o] = ctx.constraints[i];
|
|
||||||
}
|
|
||||||
o++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.constraints.length = o;
|
|
||||||
|
|
||||||
function indexVariables() {
|
|
||||||
for (let i=0; i<ctx.constraints.length; i++) linkSignalsConstraint(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
function linkSignalsConstraint(cidx) {
|
|
||||||
const ct = ctx.constraints[cidx];
|
|
||||||
for (let k in ct.a.coefs) linkSignal(k, cidx);
|
|
||||||
for (let k in ct.b.coefs) linkSignal(k, cidx);
|
|
||||||
for (let k in ct.c.coefs) linkSignal(k, cidx);
|
|
||||||
}
|
|
||||||
|
|
||||||
function unindexVariables() {
|
|
||||||
for (let s=0; s<ctx.signals.length; s++) {
|
|
||||||
let lSignal = ctx.signals[s];
|
|
||||||
while (lSignal.e>=0) {
|
|
||||||
lSignal = ctx.signals[lSignal.e];
|
|
||||||
}
|
|
||||||
if (lSignal.inConstraints) delete lSignal.inConstraints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
function unlinkSignal(signalName, cidx) {
|
|
||||||
let lSignal = ctx.signals[signalName];
|
|
||||||
while (lSignal.e>=0) {
|
|
||||||
lSignal = ctx.signals[lSignal.e];
|
|
||||||
}
|
|
||||||
if ((lSignal.inConstraints)&&(lSignal.inConstraints[cidx])) {
|
|
||||||
delete lSignal.inConstraints[cidx];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function linkSignal(signalName, cidx) {
|
|
||||||
let lSignal = ctx.signals[signalName];
|
|
||||||
while (lSignal.e>=0) {
|
|
||||||
lSignal = ctx.signals[lSignal.e];
|
|
||||||
}
|
|
||||||
if (!lSignal.inConstraints) lSignal.inConstraints = {};
|
|
||||||
lSignal.inConstraints[cidx] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFirstInternalSignal(ctx, l) {
|
|
||||||
for (let k in l.coefs) {
|
|
||||||
const signal = ctx.signals[k];
|
|
||||||
if (signal.c == ctx.stINTERNAL) return k;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 buildCircuitDef(ctx, mainCode) {
|
|
||||||
const res = {
|
|
||||||
mainCode: mainCode
|
|
||||||
};
|
|
||||||
res.signalName2Idx = ctx.signalName2Idx;
|
|
||||||
|
|
||||||
res.components = [];
|
|
||||||
res.componentName2Idx = {};
|
|
||||||
for (let c in ctx.components) {
|
|
||||||
const idCoponent = res.components.length;
|
|
||||||
res.components.push({
|
|
||||||
name: c,
|
|
||||||
params: ctx.components[c].params,
|
|
||||||
template: ctx.components[c].template,
|
|
||||||
inputSignals: 0
|
|
||||||
});
|
|
||||||
res.componentName2Idx[c] = idCoponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.signals = new Array(ctx.signalNames.length);
|
|
||||||
for (let i=0; i<ctx.signalNames.length; i++) {
|
|
||||||
res.signals[i] = {
|
|
||||||
names: ctx.signalNames[i],
|
|
||||||
triggerComponents: []
|
|
||||||
};
|
|
||||||
ctx.signalNames[i].map( (fullName) => {
|
|
||||||
const idComponet = res.componentName2Idx[ctx.signals[fullName].component];
|
|
||||||
if (ctx.signals[fullName].direction == "IN") {
|
|
||||||
res.signals[i].triggerComponents.push(idComponet);
|
|
||||||
res.components[idComponet].inputSignals++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
res.constraints = buildConstraints(ctx);
|
|
||||||
|
|
||||||
res.templates = ctx.templates;
|
|
||||||
|
|
||||||
res.functions = {};
|
|
||||||
for (let f in ctx.functions) {
|
|
||||||
res.functions[f] = {
|
|
||||||
params: ctx.functionParams[f],
|
|
||||||
func: ctx.functions[f]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
res.nPrvInputs = ctx.totals.prvInput;
|
|
||||||
res.nPubInputs = ctx.totals.pubInput;
|
|
||||||
res.nInputs = res.nPrvInputs + res.nPubInputs;
|
|
||||||
res.nOutputs = ctx.totals.output;
|
|
||||||
res.nVars = res.nInputs + res.nOutputs + ctx.totals.one + ctx.totals.internal;
|
|
||||||
res.nConstants = ctx.totals.constant;
|
|
||||||
res.nSignals = res.nVars + res.nConstants;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Build constraints
|
|
||||||
|
|
||||||
A constraint like this
|
|
||||||
|
|
||||||
[s1 + 2*s2 + 3*s3] * [ s2 + 5*s4] - [s0 ] = 0
|
|
||||||
[ 5*s2 + 6*s3] * [ s2 + ] - [s0 + 2* s2] = 0
|
|
||||||
[s1 + s3] * [ s2 + 5*s3] - [s4 ] = 0
|
|
||||||
|
|
||||||
is converted to
|
|
||||||
|
|
||||||
[
|
|
||||||
[{"1":"1","2":"2","3":"3"} , {"2":"1","4":"5"} , {"0":"1" }],
|
|
||||||
[{ "2":"5","3":"6"} , {"2":"1" } , {"0":"1", "2":"2"}],
|
|
||||||
[{"1":"1", "3":"1"} , {"2":"1","3":"5"} , {"4":"1" }]
|
|
||||||
]
|
|
||||||
^ ^ ^
|
|
||||||
| | |
|
|
||||||
A B C
|
|
||||||
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
function buildConstraints(ctx) {
|
|
||||||
const res = [];
|
|
||||||
|
|
||||||
function fillLC(dst, src) {
|
|
||||||
if (src.t != "LC") throw new Error("Constraint is not a LINEARCOMBINATION");
|
|
||||||
for (let s in src.coefs) {
|
|
||||||
const v = src.coefs[s].toString();
|
|
||||||
const id = ctx.signalName2Idx[s];
|
|
||||||
dst[id] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i=0; i<ctx.constraints.length; i++) {
|
|
||||||
const A = {};
|
|
||||||
const B = {};
|
|
||||||
const C = {};
|
|
||||||
|
|
||||||
fillLC(A, ctx.constraints[i].a);
|
|
||||||
fillLC(B, ctx.constraints[i].b);
|
|
||||||
fillLC(C, ctx.lc.negate(ctx.constraints[i].c));
|
|
||||||
|
|
||||||
res.push([A,B,C]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
function buildSyms(ctx, strm) {
|
|
||||||
|
|
||||||
let nSyms;
|
|
||||||
|
|
||||||
addSymbolsComponent(ctx.mainComponent + ".", ctx.getComponentIdx(ctx.mainComponent));
|
|
||||||
|
|
||||||
|
|
||||||
function addSymbolsComponent(prefix, idComponet) {
|
|
||||||
for (let n in ctx.components[idComponet].names.o) {
|
|
||||||
const entrie = ctx.components[idComponet].names.o[n];
|
|
||||||
addSymbolArray(prefix+n, entrie.type, entrie.sizes, entrie.offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addSymbolArray(prefix, type, sizes, offset) {
|
|
||||||
if (sizes.length==0) {
|
|
||||||
if (type == "S") {
|
|
||||||
let s=offset;
|
|
||||||
while (ctx.signals[s].e >= 0) s = ctx.signals[s].e;
|
|
||||||
let wId = ctx.signals[s].id;
|
|
||||||
if (typeof(wId) == "undefined") wId=-1;
|
|
||||||
strm.write(`${offset},${wId},${prefix}\n`);
|
|
||||||
nSyms ++;
|
|
||||||
if ((ctx.verbose)&&(nSyms%10000 == 0)) console.log("Symbols saved: "+nSyms);
|
|
||||||
} else {
|
|
||||||
addSymbolsComponent(prefix+".", offset);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
let acc = 0;
|
|
||||||
for (let i=0; i<sizes[0]; i++) {
|
|
||||||
acc += addSymbolArray(`${prefix}[${i}]`, type, sizes.slice(1), offset + acc );
|
|
||||||
}
|
|
||||||
return acc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|||||||
@@ -567,9 +567,13 @@ function execFunctionCall(ctx, ast) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ast.name == "assert") {
|
if (ast.name == "assert") {
|
||||||
|
ast.fileName = ctx.fileName;
|
||||||
|
ast.filePath = ctx.filePath;
|
||||||
|
|
||||||
const v = exec(ctx, ast.params[0]);
|
const v = exec(ctx, ast.params[0]);
|
||||||
const ev = val(ctx, v, ast);
|
const ev = val(ctx, v, ast);
|
||||||
if (ctx.F.isZero(ev)) return ctx.throwError(ast, "Assertion failed");
|
if ((typeof ev.v !== "undefined")&&(ctx.F.isZero(ev.v))) return ctx.throwError(ast, "Assertion failed");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fnc = ctx.functions[ast.name];
|
const fnc = ctx.functions[ast.name];
|
||||||
|
|||||||
@@ -723,7 +723,15 @@ function genVarAssignment(ctx, ast, lRef, sels, rRef) {
|
|||||||
|
|
||||||
if (instantiated) {
|
if (instantiated) {
|
||||||
if (offset.used) {
|
if (offset.used) {
|
||||||
ctx.codeBuilder.copyN(left.label, ["R", offset.label], ["R", right.label], right.sizes[0]);
|
let ot;
|
||||||
|
if (offset.type == "BIGINT") {
|
||||||
|
ot = "R";
|
||||||
|
} else if (offset.type == "INT") {
|
||||||
|
ot= "RI";
|
||||||
|
} else {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
ctx.codeBuilder.copyN(left.label, [ot, offset.label], ["R", right.label], right.sizes[0]);
|
||||||
} else {
|
} else {
|
||||||
ctx.codeBuilder.copyN(left.label, ["V", offset.value[0]], ["R", right.label], right.sizes[0]);
|
ctx.codeBuilder.copyN(left.label, ["V", offset.value[0]], ["R", right.label], right.sizes[0]);
|
||||||
}
|
}
|
||||||
@@ -863,6 +871,12 @@ function genFunctionCall(ctx, ast) {
|
|||||||
ctx.codeBuilder.log(toRefA_Fr1(ctx, ast.params[0], vRef));
|
ctx.codeBuilder.log(toRefA_Fr1(ctx, ast.params[0], vRef));
|
||||||
return vRef;
|
return vRef;
|
||||||
}
|
}
|
||||||
|
if (ast.name == "assert") {
|
||||||
|
const strErr = ast.fileName + ":" + ast.first_line + ":" + ast.first_column;
|
||||||
|
const vRef = gen(ctx, ast.params[0]);
|
||||||
|
ctx.codeBuilder.checkAssert(toRefA_Fr1(ctx, ast.params[0], vRef), strErr);
|
||||||
|
return vRef;
|
||||||
|
}
|
||||||
const params = [];
|
const params = [];
|
||||||
for (let i=0; i<ast.params.length; i++) {
|
for (let i=0; i<ast.params.length; i++) {
|
||||||
const pRef = gen(ctx, ast.params[i]);
|
const pRef = gen(ctx, ast.params[i]);
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ async function buildR1cs(ctx, fileName) {
|
|||||||
if ((ctx.verbose)&&(i%10000 == 0)) {
|
if ((ctx.verbose)&&(i%10000 == 0)) {
|
||||||
if (ctx.verbose) console.log("writing constraint: ", i);
|
if (ctx.verbose) console.log("writing constraint: ", i);
|
||||||
}
|
}
|
||||||
await writeConstraint(ctx.constraints[i]);
|
await writeConstraint(ctx.constraints[i], i);
|
||||||
}
|
}
|
||||||
|
|
||||||
const constraintsSize = fd.pos - pConstraintsSize - 8;
|
const constraintsSize = fd.pos - pConstraintsSize - 8;
|
||||||
@@ -89,13 +89,13 @@ async function buildR1cs(ctx, fileName) {
|
|||||||
const mapSize = fd.pos - pMapSize - 8;
|
const mapSize = fd.pos - pMapSize - 8;
|
||||||
|
|
||||||
// Write sizes
|
// Write sizes
|
||||||
await fd.writeULE32(headerSize, pHeaderSize);
|
await fd.writeULE64(headerSize, pHeaderSize);
|
||||||
await fd.writeULE32(constraintsSize, pConstraintsSize);
|
await fd.writeULE64(constraintsSize, pConstraintsSize);
|
||||||
await fd.writeULE32(mapSize, pMapSize);
|
await fd.writeULE64(mapSize, pMapSize);
|
||||||
|
|
||||||
await fd.close();
|
await fd.close();
|
||||||
|
|
||||||
function writeConstraint(c) {
|
function writeConstraint(c, ctIdx) {
|
||||||
const n8 = ctx.F.n8;
|
const n8 = ctx.F.n8;
|
||||||
const idxA = Object.keys(c.a.coefs);
|
const idxA = Object.keys(c.a.coefs);
|
||||||
const idxB = Object.keys(c.b.coefs);
|
const idxB = Object.keys(c.b.coefs);
|
||||||
@@ -109,6 +109,7 @@ async function buildR1cs(ctx, fileName) {
|
|||||||
const coef = idxA[i];
|
const coef = idxA[i];
|
||||||
let lSignal = ctx.signals[coef];
|
let lSignal = ctx.signals[coef];
|
||||||
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
||||||
|
if (lSignal.id >= NWires) throw new Error("Signal Coef A: " + coef + " Constraint: " + ctIdx + " id: " + lSignal.id);
|
||||||
buffV.setUint32(o, lSignal.id, true); o+=4;
|
buffV.setUint32(o, lSignal.id, true); o+=4;
|
||||||
ctx.F.toRprLE(buff, o, c.a.coefs[coef]); o+=n8;
|
ctx.F.toRprLE(buff, o, c.a.coefs[coef]); o+=n8;
|
||||||
}
|
}
|
||||||
@@ -118,8 +119,8 @@ async function buildR1cs(ctx, fileName) {
|
|||||||
const coef = idxB[i];
|
const coef = idxB[i];
|
||||||
let lSignal = ctx.signals[coef];
|
let lSignal = ctx.signals[coef];
|
||||||
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
||||||
|
if (lSignal.id >= NWires) throw new Error("Signal Coef B: " + coef + " Constraint: " + ctIdx + " id: " + lSignal.id);
|
||||||
buffV.setUint32(o, lSignal.id, true); o+=4;
|
buffV.setUint32(o, lSignal.id, true); o+=4;
|
||||||
|
|
||||||
ctx.F.toRprLE(buff, o, c.b.coefs[coef]); o+=n8;
|
ctx.F.toRprLE(buff, o, c.b.coefs[coef]); o+=n8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +129,7 @@ async function buildR1cs(ctx, fileName) {
|
|||||||
const coef = idxC[i];
|
const coef = idxC[i];
|
||||||
let lSignal = ctx.signals[coef];
|
let lSignal = ctx.signals[coef];
|
||||||
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
||||||
|
if (lSignal.id >= NWires) throw new Error("Signal Coef C: " + coef + " Constraint: " + ctIdx + " id: " + lSignal.id);
|
||||||
buffV.setUint32(o, lSignal.id, true); o+=4;
|
buffV.setUint32(o, lSignal.id, true); o+=4;
|
||||||
ctx.F.toRprLE(buff, o, ctx.F.neg(c.c.coefs[coef])); o+=n8;
|
ctx.F.toRprLE(buff, o, ctx.F.neg(c.c.coefs[coef])); o+=n8;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user