mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-06 18:56:40 +01:00
Construction phase redone
This commit is contained in:
@@ -87,7 +87,7 @@ function instantiateConstant(ctx, value) {
|
|||||||
function createRefs(ctx, ast) {
|
function createRefs(ctx, ast) {
|
||||||
const scopeLabels = [];
|
const scopeLabels = [];
|
||||||
iterateAST(ast, (ast, level) => {
|
iterateAST(ast, (ast, level) => {
|
||||||
while ((scopeLabels.length>0)&&(!scopeLabels[scopeLabels.length-1].startsWith(level))) {
|
while ((scopeLabels.length>0)&&(!level.startsWith(scopeLabels[scopeLabels.length-1]))) {
|
||||||
ctx.scopes.pop();
|
ctx.scopes.pop();
|
||||||
scopeLabels.pop();
|
scopeLabels.pop();
|
||||||
}
|
}
|
||||||
@@ -329,7 +329,7 @@ function genDeclareVariable(ctx, ast) {
|
|||||||
}
|
}
|
||||||
sizes = utils.accSizes(sizes);
|
sizes = utils.accSizes(sizes);
|
||||||
} else {
|
} else {
|
||||||
sizes = null; // If not sizes, the sized are defined in the first assignement.
|
sizes = [1,0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!v.sizes)&&(sizes)) {
|
if ((!v.sizes)&&(sizes)) {
|
||||||
|
|||||||
@@ -17,26 +17,18 @@
|
|||||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fs = require("fs");
|
|
||||||
const path = require("path");
|
|
||||||
const bigInt = require("big-integer");
|
const bigInt = require("big-integer");
|
||||||
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||||
const sONE = 0;
|
const sONE = 0;
|
||||||
const assert = require("assert");
|
|
||||||
const buildC = require("./c_build");
|
const buildC = require("./c_build");
|
||||||
const exec = require("./exec");
|
const constructionPhase = require("./construction_phase");
|
||||||
const lc = require("./lcalgebra");
|
|
||||||
const Ctx = require("./ctx");
|
const Ctx = require("./ctx");
|
||||||
const ZqField = require("./zqfield");
|
const ZqField = require("fflib").ZqField;
|
||||||
const utils = require("./utils");
|
const utils = require("./utils");
|
||||||
const buildR1cs = require("./r1csfile").buildR1cs;
|
const buildR1cs = require("./r1csfile").buildR1cs;
|
||||||
|
|
||||||
module.exports = compile;
|
module.exports = compile;
|
||||||
|
|
||||||
const parser = require("../parser/jaz.js").parser;
|
|
||||||
|
|
||||||
const timeout = ms => new Promise(res => setTimeout(res, ms));
|
|
||||||
|
|
||||||
async function compile(srcFile, options) {
|
async function compile(srcFile, options) {
|
||||||
options.p = options.p || __P__;
|
options.p = options.p || __P__;
|
||||||
if (!options) {
|
if (!options) {
|
||||||
@@ -45,26 +37,15 @@ async function compile(srcFile, options) {
|
|||||||
if (typeof options.reduceConstraints === "undefined") {
|
if (typeof options.reduceConstraints === "undefined") {
|
||||||
options.reduceConstraints = true;
|
options.reduceConstraints = true;
|
||||||
}
|
}
|
||||||
const fullFileName = srcFile;
|
|
||||||
const fullFilePath = path.dirname(fullFileName);
|
|
||||||
|
|
||||||
const src = fs.readFileSync(fullFileName, "utf8");
|
|
||||||
const ast = parser.parse(src);
|
|
||||||
|
|
||||||
assert(ast.type == "BLOCK");
|
|
||||||
|
|
||||||
const ctx = new Ctx();
|
const ctx = new Ctx();
|
||||||
ctx.field = new ZqField(options.p);
|
ctx.field = new ZqField(options.p);
|
||||||
ctx.mainComponent = options.mainComponent || "main";
|
|
||||||
ctx.filePath= fullFilePath;
|
|
||||||
ctx.fileName= fullFileName;
|
|
||||||
ctx.includedFiles = {};
|
|
||||||
ctx.includedFiles[fullFileName] = src.split("\n");
|
|
||||||
|
|
||||||
ctx.verbose= options.verbose || false;
|
ctx.verbose= options.verbose || false;
|
||||||
|
ctx.mainComponent = options.mainComponent || "main";
|
||||||
|
|
||||||
|
|
||||||
exec(ctx, ast);
|
constructionPhase(ctx, srcFile);
|
||||||
|
|
||||||
|
console.log("NConstraints Before: "+ctx.constraints.length);
|
||||||
|
|
||||||
if (ctx.error) {
|
if (ctx.error) {
|
||||||
throw(ctx.error);
|
throw(ctx.error);
|
||||||
@@ -91,6 +72,8 @@ async function compile(srcFile, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("NConstraints After: "+ctx.constraints.length);
|
||||||
|
|
||||||
generateWitnessNames(ctx);
|
generateWitnessNames(ctx);
|
||||||
|
|
||||||
if (ctx.error) {
|
if (ctx.error) {
|
||||||
@@ -235,8 +218,8 @@ function reduceConstants(ctx) {
|
|||||||
const newConstraints = [];
|
const newConstraints = [];
|
||||||
for (let i=0; i<ctx.constraints.length; i++) {
|
for (let i=0; i<ctx.constraints.length; i++) {
|
||||||
if ((ctx.verbose)&&(i%10000 == 0)) console.log("reducing constants: ", i);
|
if ((ctx.verbose)&&(i%10000 == 0)) console.log("reducing constants: ", i);
|
||||||
const c = lc.canonize(ctx, ctx.constraints[i]);
|
const c = ctx.lc.canonize(ctx, ctx.constraints[i]);
|
||||||
if (!lc.isZero(c)) {
|
if (!ctx.lc.isZero(c)) {
|
||||||
newConstraints.push(c);
|
newConstraints.push(c);
|
||||||
}
|
}
|
||||||
delete ctx.constraints[i];
|
delete ctx.constraints[i];
|
||||||
@@ -265,19 +248,19 @@ function reduceConstrains(ctx) {
|
|||||||
|
|
||||||
// Mov to C if possible.
|
// Mov to C if possible.
|
||||||
if (isConstant(c.a)) {
|
if (isConstant(c.a)) {
|
||||||
const ct = {type: "NUMBER", value: c.a.values[sONE]};
|
const ct = {t: "N", v: c.a.coefs[sONE]};
|
||||||
c.c = lc.add(lc.mul(c.b, ct), c.c);
|
c.c = ctx.lc.add(ctx.lc.mul(c.b, ct), c.c);
|
||||||
c.a = { type: "LINEARCOMBINATION", values: {} };
|
c.a = { t: "LC", coefs: {} };
|
||||||
c.b = { type: "LINEARCOMBINATION", values: {} };
|
c.b = { t: "LC", coefs: {} };
|
||||||
}
|
}
|
||||||
if (isConstant(c.b)) {
|
if (isConstant(c.b)) {
|
||||||
const ct = {type: "NUMBER", value: c.b.values[sONE]};
|
const ct = {t: "N", v: c.b.coefs[sONE]};
|
||||||
c.c = lc.add(lc.mul(c.a, ct), c.c);
|
c.c = ctx.lc.add(ctx.lc.mul(c.a, ct), c.c);
|
||||||
c.a = { type: "LINEARCOMBINATION", values: {} };
|
c.a = { t: "LC", coefs: {} };
|
||||||
c.b = { type: "LINEARCOMBINATION", values: {} };
|
c.b = { t: "LC", coefs: {} };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lc.isZero(c.a) || lc.isZero(c.b)) {
|
if (ctx.lc.isZero(c.a) || ctx.lc.isZero(c.b)) {
|
||||||
const isolatedSignal = getFirstInternalSignal(ctx, c.c);
|
const isolatedSignal = getFirstInternalSignal(ctx, c.c);
|
||||||
if (isolatedSignal) {
|
if (isolatedSignal) {
|
||||||
|
|
||||||
@@ -288,22 +271,22 @@ function reduceConstrains(ctx) {
|
|||||||
|
|
||||||
|
|
||||||
const isolatedSignalEquivalence = {
|
const isolatedSignalEquivalence = {
|
||||||
type: "LINEARCOMBINATION",
|
t: "LC",
|
||||||
values: {}
|
coefs: {}
|
||||||
};
|
};
|
||||||
const invCoef = c.c.values[isolatedSignal].modInv(__P__);
|
const invCoef = c.c.coefs[isolatedSignal].modInv(__P__);
|
||||||
for (const s in c.c.values) {
|
for (const s in c.c.coefs) {
|
||||||
if (s != isolatedSignal) {
|
if (s != isolatedSignal) {
|
||||||
const v = __P__.minus(c.c.values[s]).times(invCoef).mod(__P__);
|
const v = __P__.minus(c.c.coefs[s]).times(invCoef).mod(__P__);
|
||||||
if (!v.isZero()) {
|
if (!v.isZero()) {
|
||||||
isolatedSignalEquivalence.values[s] = v;
|
isolatedSignalEquivalence.coefs[s] = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let j in lSignal.inConstraints) {
|
for (let j in lSignal.inConstraints) {
|
||||||
if ((j!=i)&&(ctx.constraints[j])) {
|
if ((j!=i)&&(ctx.constraints[j])) {
|
||||||
ctx.constraints[j] = lc.substitute(ctx.constraints[j], isolatedSignal, isolatedSignalEquivalence);
|
ctx.constraints[j] = ctx.lc.substitute(ctx.constraints[j], isolatedSignal, isolatedSignalEquivalence);
|
||||||
linkSignalsConstraint(j);
|
linkSignalsConstraint(j);
|
||||||
if (j<i) {
|
if (j<i) {
|
||||||
nextPossibleConstraints[j] = true;
|
nextPossibleConstraints[j] = true;
|
||||||
@@ -315,7 +298,7 @@ function reduceConstrains(ctx) {
|
|||||||
|
|
||||||
lSignal.c = ctx.stDISCARDED;
|
lSignal.c = ctx.stDISCARDED;
|
||||||
} else {
|
} else {
|
||||||
if (lc.isZero(c.c)) ctx.constraints[i] = null;
|
if (ctx.lc.isZero(c.c)) ctx.constraints[i] = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -341,9 +324,9 @@ function reduceConstrains(ctx) {
|
|||||||
|
|
||||||
function linkSignalsConstraint(cidx) {
|
function linkSignalsConstraint(cidx) {
|
||||||
const ct = ctx.constraints[cidx];
|
const ct = ctx.constraints[cidx];
|
||||||
for (let k in ct.a.values) linkSignal(k, cidx);
|
for (let k in ct.a.coefs) linkSignal(k, cidx);
|
||||||
for (let k in ct.b.values) linkSignal(k, cidx);
|
for (let k in ct.b.coefs) linkSignal(k, cidx);
|
||||||
for (let k in ct.c.values) linkSignal(k, cidx);
|
for (let k in ct.c.coefs) linkSignal(k, cidx);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unindexVariables() {
|
function unindexVariables() {
|
||||||
@@ -378,7 +361,7 @@ function reduceConstrains(ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getFirstInternalSignal(ctx, l) {
|
function getFirstInternalSignal(ctx, l) {
|
||||||
for (let k in l.values) {
|
for (let k in l.coefs) {
|
||||||
const signal = ctx.signals[k];
|
const signal = ctx.signals[k];
|
||||||
if (signal.c == ctx.stINTERNAL) return k;
|
if (signal.c == ctx.stINTERNAL) return k;
|
||||||
}
|
}
|
||||||
@@ -386,10 +369,10 @@ function reduceConstrains(ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isConstant(l) {
|
function isConstant(l) {
|
||||||
for (let k in l.values) {
|
for (let k in l.coefs) {
|
||||||
if ((k != sONE) && (!l.values[k].isZero())) return false;
|
if ((k != sONE) && (!l.coefs[k].isZero())) return false;
|
||||||
}
|
}
|
||||||
if (!l.values[sONE] || l.values[sONE].isZero()) return false;
|
if (!l.coefs[sONE] || l.coefs[sONE].isZero()) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -483,9 +466,9 @@ function buildConstraints(ctx) {
|
|||||||
const res = [];
|
const res = [];
|
||||||
|
|
||||||
function fillLC(dst, src) {
|
function fillLC(dst, src) {
|
||||||
if (src.type != "LINEARCOMBINATION") throw new Error("Constraint is not a LINEARCOMBINATION");
|
if (src.t != "LC") throw new Error("Constraint is not a LINEARCOMBINATION");
|
||||||
for (let s in src.values) {
|
for (let s in src.coefs) {
|
||||||
const v = src.values[s].toString();
|
const v = src.coefs[s].toString();
|
||||||
const id = ctx.signalName2Idx[s];
|
const id = ctx.signalName2Idx[s];
|
||||||
dst[id] = v;
|
dst[id] = v;
|
||||||
}
|
}
|
||||||
@@ -498,7 +481,7 @@ function buildConstraints(ctx) {
|
|||||||
|
|
||||||
fillLC(A, ctx.constraints[i].a);
|
fillLC(A, ctx.constraints[i].a);
|
||||||
fillLC(B, ctx.constraints[i].b);
|
fillLC(B, ctx.constraints[i].b);
|
||||||
fillLC(C, lc.negate(ctx.constraints[i].c));
|
fillLC(C, ctx.lc.negate(ctx.constraints[i].c));
|
||||||
|
|
||||||
res.push([A,B,C]);
|
res.push([A,B,C]);
|
||||||
}
|
}
|
||||||
|
|||||||
1070
src/construction_phase.js
Normal file
1070
src/construction_phase.js
Normal file
File diff suppressed because it is too large
Load Diff
1335
src/exec.js
1335
src/exec.js
File diff suppressed because it is too large
Load Diff
@@ -61,6 +61,12 @@ function iterateAST(ast, fn, _pfx) {
|
|||||||
iterateAST(ast.value, fn, getPfx());
|
iterateAST(ast.value, fn, getPfx());
|
||||||
} else if (ast.type == "ARRAY") {
|
} else if (ast.type == "ARRAY") {
|
||||||
iterate(ast.values);
|
iterate(ast.values);
|
||||||
|
} else if ((ast.type == "TEMPLATEDEF")) {
|
||||||
|
//
|
||||||
|
} else if ((ast.type == "FUNCTIONDEF")) {
|
||||||
|
//
|
||||||
|
} else if ((ast.type == "INCLUDE")) {
|
||||||
|
//
|
||||||
} else {
|
} else {
|
||||||
assert(false, "GEN -> Invalid AST iteration: " + ast.type);
|
assert(false, "GEN -> Invalid AST iteration: " + ast.type);
|
||||||
}
|
}
|
||||||
|
|||||||
972
src/lcalgebra.js
972
src/lcalgebra.js
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,6 @@
|
|||||||
|
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const assert = require("assert");
|
const assert = require("assert");
|
||||||
const lc = require("./lcalgebra");
|
|
||||||
const bigInt = require("big-integer");
|
const bigInt = require("big-integer");
|
||||||
|
|
||||||
module.exports.buildR1cs = buildR1cs;
|
module.exports.buildR1cs = buildR1cs;
|
||||||
@@ -262,19 +261,19 @@ async function buildR1cs(ctx, fileName) {
|
|||||||
async function writeConstraint(c) {
|
async function writeConstraint(c) {
|
||||||
await writeLC(c.a);
|
await writeLC(c.a);
|
||||||
await writeLC(c.b);
|
await writeLC(c.b);
|
||||||
await writeLC(lc.negate(c.c));
|
await writeLC(ctx.lc.neg(c.c));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function writeLC(lc) {
|
async function writeLC(lc) {
|
||||||
const idxs = Object.keys(lc.values);
|
const idxs = Object.keys(lc.coefs);
|
||||||
await writeU32(idxs.length);
|
await writeU32(idxs.length);
|
||||||
for (let s in lc.values) {
|
for (let s in lc.coefs) {
|
||||||
let lSignal = ctx.signals[s];
|
let lSignal = ctx.signals[s];
|
||||||
|
|
||||||
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
||||||
|
|
||||||
await writeU32(lSignal.id);
|
await writeU32(lSignal.id);
|
||||||
await writeBigInt(lc.values[s]);
|
await writeBigInt(lc.coefs[s]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,3 +124,4 @@ function accSizes2Str(sizes) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
118
src/zqfield.js
118
src/zqfield.js
@@ -1,118 +0,0 @@
|
|||||||
const bigInt = require("big-integer");
|
|
||||||
const assert = require("assert");
|
|
||||||
|
|
||||||
module.exports = class ZqField {
|
|
||||||
constructor(p) {
|
|
||||||
this.one = bigInt.one;
|
|
||||||
this.zero = bigInt.zero;
|
|
||||||
this.p = p;
|
|
||||||
this.bitLength = p.bitLength();
|
|
||||||
this.mask = bigInt.one.shiftLeft(this.bitLength - 1).minus(bigInt.one);
|
|
||||||
}
|
|
||||||
|
|
||||||
add(a, b) {
|
|
||||||
let res = a.add(b);
|
|
||||||
if (res.geq(this.p)) {
|
|
||||||
res = res.minus(this.p);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub(a, b) {
|
|
||||||
if (a.geq(b)) {
|
|
||||||
return a.minus(b);
|
|
||||||
} else {
|
|
||||||
return this.p.minus(b.minus(a));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
neg(a) {
|
|
||||||
if (a.isZero()) return a;
|
|
||||||
return this.p.minus(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
mul(a, b) {
|
|
||||||
return a.times(b).mod(this.p);
|
|
||||||
}
|
|
||||||
|
|
||||||
lt(a, b) {
|
|
||||||
return a.lt(b) ? bigInt(1) : bigInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
eq(a, b) {
|
|
||||||
return a.eq(b) ? bigInt(1) : bigInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
gt(a, b) {
|
|
||||||
return a.gt(b) ? bigInt(1) : bigInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
leq(a, b) {
|
|
||||||
return a.leq(b) ? bigInt(1) : bigInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
geq(a, b) {
|
|
||||||
return a.geq(b) ? bigInt(1) : bigInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
neq(a, b) {
|
|
||||||
return a.neq(b) ? bigInt(1) : bigInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
div(a, b) {
|
|
||||||
assert(!b.isZero(), "Division by zero");
|
|
||||||
return a.times(b.modInv(this.p)).mod(this.p);
|
|
||||||
}
|
|
||||||
|
|
||||||
idiv(a, b) {
|
|
||||||
assert(!b.isZero(), "Division by zero");
|
|
||||||
return a.divide(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
mod(a, b) {
|
|
||||||
return a.mod(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
pow(a, b) {
|
|
||||||
return a.modPow(b, this.p);
|
|
||||||
}
|
|
||||||
|
|
||||||
band(a, b) {
|
|
||||||
return a.and(b).and(this.mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
bor(a, b) {
|
|
||||||
return a.or(b).and(this.mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
bxor(a, b) {
|
|
||||||
return a.xor(b).and(this.mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
bnot(a) {
|
|
||||||
return a.xor(this.mask).and(this.mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
shl(a, b) {
|
|
||||||
if (b.geq(this.bitLength)) return bigInt.zero;
|
|
||||||
return a.shiftLeft(b).and(this.mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
shr(a, b) {
|
|
||||||
if (b.geq(this.bitLength)) return bigInt.zero;
|
|
||||||
return a.shiftRight(b).and(this.mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
land(a, b) {
|
|
||||||
return (a.isZero() || b.isZero) ? bigInt.zero : bigInt.one;
|
|
||||||
}
|
|
||||||
|
|
||||||
lor(a, b) {
|
|
||||||
return (a.isZero() && b.isZero) ? bigInt.zero : bigInt.one;
|
|
||||||
}
|
|
||||||
|
|
||||||
lnot(a) {
|
|
||||||
return a.isZero() ? bigInt.one : bigInt.zero;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -44,7 +44,8 @@ async function doTest(circuit, testVectors) {
|
|||||||
|
|
||||||
describe("basic cases", function () {
|
describe("basic cases", function () {
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
/* it("inout", async () => {
|
/*
|
||||||
|
it("inout", async () => {
|
||||||
await doTest(
|
await doTest(
|
||||||
"inout.circom",
|
"inout.circom",
|
||||||
[
|
[
|
||||||
@@ -298,6 +299,17 @@ describe("basic cases", function () {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
|
it("Component array 2d", async () => {
|
||||||
|
await doTest(
|
||||||
|
"componentarray2.circom",
|
||||||
|
[
|
||||||
|
[{in: [1,2]}, {out: [1, 256]}],
|
||||||
|
[{in: [0,3]}, {out: [0, 6561]}],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
/*
|
||||||
it("Constant circuit", async () => {
|
it("Constant circuit", async () => {
|
||||||
await doTest(
|
await doTest(
|
||||||
"constantcircuit.circom",
|
"constantcircuit.circom",
|
||||||
@@ -306,12 +318,11 @@ describe("basic cases", function () {
|
|||||||
[{}, {out: [1,0,1,0, 0,0,0,1, 0,1,1,1, 0,1,0,1, 1,1,1,0, 0,1,1,0, 1,1,0,1, 1,1,0,1]}],
|
[{}, {out: [1,0,1,0, 0,0,0,1, 0,1,1,1, 0,1,0,1, 1,1,1,0, 0,1,1,0, 1,1,0,1, 1,1,0,1]}],
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}); */
|
});
|
||||||
it("Constant internal circuit", async () => {
|
it("Constant internal circuit", async () => {
|
||||||
await doTest(
|
await doTest(
|
||||||
"constantinternalcircuit.circom",
|
"constantinternalcircuit.circom",
|
||||||
[
|
[
|
||||||
// 0xbb67ae85
|
|
||||||
[{in: 1}, {out: 5}],
|
[{in: 1}, {out: 5}],
|
||||||
[{in: 0}, {out: 4}],
|
[{in: 0}, {out: 4}],
|
||||||
[{in: -2}, {out: 2}],
|
[{in: -2}, {out: 2}],
|
||||||
@@ -319,4 +330,14 @@ describe("basic cases", function () {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
it("include", async () => {
|
||||||
|
await doTest(
|
||||||
|
"include.circom",
|
||||||
|
[
|
||||||
|
[{in: 3}, {out: 6}],
|
||||||
|
[{in: 6}, {out: 15}],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
*/
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,18 +4,15 @@
|
|||||||
function Add3(arr1, arr2, arr3) {
|
function Add3(arr1, arr2, arr3) {
|
||||||
var res[3];
|
var res[3];
|
||||||
|
|
||||||
var i;
|
|
||||||
var j;
|
|
||||||
|
|
||||||
res[0] = arr1;
|
res[0] = arr1;
|
||||||
res[1] = 0;
|
res[1] = 0;
|
||||||
for (i=0; i<2; i += 1) {
|
for (var i=0; i<2; i += 1) {
|
||||||
res[1] = res[1] + arr2[i];
|
res[1] = res[1] + arr2[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
res[2] = 0;
|
res[2] = 0;
|
||||||
for (i=0; i<2; i++) {
|
for (var i=0; i<2; i++) {
|
||||||
for (j=0; j<3; j += 1) {
|
for (var j=0; j<3; j += 1) {
|
||||||
res[2] = res[2] + arr3[i][j];
|
res[2] = res[2] + arr3[i][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,8 +24,8 @@ template Main() {
|
|||||||
signal input in;
|
signal input in;
|
||||||
signal output out[3];
|
signal output out[3];
|
||||||
|
|
||||||
var c = Add3(1, [2,3], [[4,5,6], [7,8,9]]); // [1, 5, 39];
|
var c[3] = Add3(1, [2,3], [[4,5,6], [7,8,9]]); // [1, 5, 39];
|
||||||
var d = Add3(in, [in+1, in+2], [[in+1, in+2, in+3], [in+1, in+2, in+3]]);
|
var d[3] = Add3(in, [in+1, in+2], [[in+1, in+2, in+3], [in+1, in+2, in+3]]);
|
||||||
|
|
||||||
out[0] <-- d[0] + c[0];
|
out[0] <-- d[0] + c[0];
|
||||||
out[0] === in+c[0];
|
out[0] === in+c[0];
|
||||||
|
|||||||
27
test/circuits/componentarray2.circom
Normal file
27
test/circuits/componentarray2.circom
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
template Square() {
|
||||||
|
signal input in;
|
||||||
|
signal output out;
|
||||||
|
|
||||||
|
out <== in**2;
|
||||||
|
}
|
||||||
|
|
||||||
|
template Main(n, nrounds) {
|
||||||
|
signal input in[n];
|
||||||
|
signal output out[n];
|
||||||
|
|
||||||
|
component squares[n][nrounds];
|
||||||
|
|
||||||
|
for (var i=0; i<n; i++) {
|
||||||
|
for (var r=0; r<nrounds; r++) {
|
||||||
|
squares[i][r] = Square();
|
||||||
|
if (r==0) {
|
||||||
|
squares[i][r].in <== in[i];
|
||||||
|
} else {
|
||||||
|
squares[i][r].in <== squares[i][r-1].out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
squares[i][nrounds-1].out ==> out[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component main = Main(2, 3);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
template H(x) {
|
template H(x) {
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
var c = [0x6a09e667,
|
var c[8] = [0x6a09e667,
|
||||||
0xbb67ae85,
|
0xbb67ae85,
|
||||||
0x3c6ef372,
|
0x3c6ef372,
|
||||||
0xa54ff53a,
|
0xa54ff53a,
|
||||||
|
|||||||
16
test/circuits/include.circom
Normal file
16
test/circuits/include.circom
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
include "included.circom";
|
||||||
|
include "included.circom"; // Include twice is fine. The second one is not included
|
||||||
|
|
||||||
|
template Main() {
|
||||||
|
signal input in;
|
||||||
|
signal output out;
|
||||||
|
|
||||||
|
component t1 = T1();
|
||||||
|
|
||||||
|
var a = F1(3);
|
||||||
|
|
||||||
|
in ==> t1.in;
|
||||||
|
t1.out + a ==> out; /// out <-- in**2/3+3
|
||||||
|
}
|
||||||
|
|
||||||
|
component main = Main();
|
||||||
10
test/circuits/included.circom
Normal file
10
test/circuits/included.circom
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
template T1() {
|
||||||
|
signal input in;
|
||||||
|
signal output out;
|
||||||
|
|
||||||
|
out <== in**2/3;
|
||||||
|
}
|
||||||
|
|
||||||
|
function F1(a) {
|
||||||
|
return a**2/3;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user