Some fixes and new version

This commit is contained in:
Jordi Baylina
2018-10-21 19:44:19 +02:00
parent ac9f051067
commit 99a7489fa2
28 changed files with 660 additions and 247 deletions

View File

@@ -1,20 +1,20 @@
/*
Copyright 2018 0KIMS association.
This file is part of jaz (Zero Knowledge Circuit Compiler).
This file is part of circom (Zero Knowledge Circuit Compiler).
jaz is a free software: you can redistribute it and/or modify it
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
jaz is distributed in the hope that it will be useful, but WITHOUT
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with jaz. If not, see <https://www.gnu.org/licenses/>.
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
const fs = require("fs");
@@ -254,11 +254,11 @@ function reduceConstrains(ctx) {
}
}
for (let j=0; j<ctx.constraints.length; j++ ) {
const c2 = ctx.constraints[j];
if (i!=j) {
lc.substitute(c2, isolatedSignal, isolatedSignalEquivalence);
}
for (let j=0; j<newConstraints.length; j++) {
newConstraints[j] = lc.substitute(newConstraints[j], isolatedSignal, isolatedSignalEquivalence);
}
for (let j=i+1; j<ctx.constraints.length; j++ ) {
ctx.constraints[j] = lc.substitute(ctx.constraints[j], isolatedSignal, isolatedSignalEquivalence);
}
c.a={ type: "LINEARCOMBINATION", values: {} };
c.b={ type: "LINEARCOMBINATION", values: {} };

View File

@@ -1,20 +1,20 @@
/*
Copyright 2018 0KIMS association.
This file is part of jaz (Zero Knowledge Circuit Compiler).
This file is part of circom (Zero Knowledge Circuit Compiler).
jaz is a free software: you can redistribute it and/or modify it
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
jaz is distributed in the hope that it will be useful, but WITHOUT
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with jaz. If not, see <https://www.gnu.org/licenses/>.
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
const path = require("path");
@@ -78,6 +78,8 @@ function exec(ctx, ast) {
return execPlusPlusRight(ctx, ast);
} else if (ast.op == "PLUSPLUSLEFT") {
return execPlusPlusLeft(ctx, ast);
} else if (ast.op == "/") {
return execDiv(ctx, ast);
} else if (ast.op == "**") {
return execExp(ctx, ast);
} else if (ast.op == "&") {
@@ -176,7 +178,7 @@ function setScope(ctx, name, selectors, value) {
function setScopeArray(a, sels) {
if (sels.length == 1) {
a[sels[0]] = value;
a[sels[0].value] = value;
} else {
setScopeArray(a[sels[0]], sels.slice(1));
}
@@ -386,8 +388,7 @@ function execFunctionCall(ctx, ast) {
const v = exec(ctx, ast.params[i]);
if (ctx.error) return;
if (v.type != "NUMBER") return error(ctx, ast.params[i], "expected a number");
paramValues.push( v.value);
paramValues.push(v);
}
if (ast.params.length != paramValues.length) error(ctx, ast, "Invalid Number of parameters");
@@ -401,10 +402,7 @@ function execFunctionCall(ctx, ast) {
const scope = {};
for (let i=0; i< fnc.params.length; i++) {
scope[fnc.params[i]] = {
type: "NUMBER",
value: paramValues[i]
};
scope[fnc.params[i]] = paramValues[i];
}
ctx.fileName = fnc.fileName;
@@ -507,6 +505,14 @@ function execVariable(ctx, ast) {
if (ctx.error) return;
if (!v) return error(ctx, ast, "Variable not defined");
// If the signal has an assigned value (constant) just return the constant
if ((v.type == "SIGNAL") && (ctx.signals[v.fullName].value)) {
return {
type: "NUMBER",
value: ctx.signals[v.fullName].value
};
}
let res;
res=v;
return res;
@@ -746,6 +752,21 @@ function execExp(ctx, ast) {
};
}
function execDiv(ctx, ast) {
const a = exec(ctx, ast.values[0]);
if (ctx.error) return;
if (a.type != "NUMBER") return { type: "NUMBER" };
const b = exec(ctx, ast.values[1]);
if (ctx.error) return;
if (b.type != "NUMBER") return { type: "NUMBER" };
if (!a.value || !b.value) return { type: "NUMBER" };
if (b.value.isZero()) return error(ctx, ast, "Division by zero");
return {
type: "NUMBER",
value: a.value.times(b.value.modInv(__P__)).mod(__P__)
};
}
function execAdd(ctx, ast) {
const a = exec(ctx, ast.values[0]);
if (ctx.error) return;

View File

@@ -1,20 +1,20 @@
/*
Copyright 2018 0KIMS association.
This file is part of jaz (Zero Knowledge Circuit Compiler).
This file is part of circom (Zero Knowledge Circuit Compiler).
jaz is a free software: you can redistribute it and/or modify it
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
jaz is distributed in the hope that it will be useful, but WITHOUT
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with jaz. If not, see <https://www.gnu.org/licenses/>.
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
const bigInt = require("big-integer");
@@ -65,6 +65,8 @@ function gen(ctx, ast) {
return genPlusPlusLeft(ctx, ast);
} else if (ast.op == "**") {
return genExp(ctx, ast);
} else if (ast.op == "/") {
return genDiv(ctx, ast);
} else if (ast.op == "&") {
return genBAnd(ctx, ast);
} else if (ast.op == "<<") {
@@ -438,6 +440,15 @@ function genSub(ctx, ast) {
return `bigInt(${a}).add(__P__).sub(bigInt(${b})).mod(__P__)`;
}
function genDiv(ctx, ast) {
const a = gen(ctx, ast.values[0]);
if (ctx.error) return;
const b = gen(ctx, ast.values[1]);
if (ctx.error) return;
return `bigInt(${a}).mul( bigInt(${b}).inverse(__P__) ).mod(__P__)`;
}
function genExp(ctx, ast) {
const a = gen(ctx, ast.values[0]);
if (ctx.error) return;

View File

@@ -1,20 +1,20 @@
/*
Copyright 2018 0KIMS association.
This file is part of jaz (Zero Knowledge Circuit Compiler).
This file is part of circom (Zero Knowledge Circuit Compiler).
jaz is a free software: you can redistribute it and/or modify it
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
jaz is distributed in the hope that it will be useful, but WITHOUT
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with jaz. If not, see <https://www.gnu.org/licenses/>.
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
/*
@@ -434,59 +434,73 @@ function toString(a, ctx) {
function canonize(ctx, a) {
if (a.type == "LINEARCOMBINATION") {
const res = clone(a);
for (let k in a.values) {
let s = k;
while (ctx.signals[s].equivalence) s= ctx.signals[s].equivalence;
if ((typeof(ctx.signals[s].value) != "undefined")&&(k != "one")) {
const v = a.values[k].times(ctx.signals[s].value).mod(__P__);
if (!a.values["one"]) {
a.values["one"]=v;
const v = res.values[k].times(ctx.signals[s].value).mod(__P__);
if (!res.values["one"]) {
res.values["one"]=v;
} else {
a.values["one"]= a.values["one"].add(v).mod(__P__);
res.values["one"]= res.values["one"].add(v).mod(__P__);
}
delete a.values[k];
delete res.values[k];
} else if (s != k) {
if (!a.values[s]) {
a.values[s]=bigInt(a.values[k]);
if (!res.values[s]) {
res.values[s]=bigInt(res.values[k]);
} else {
a.values[s]= a.values[s].add(a.values[k]).mod(__P__);
res.values[s]= res.values[s].add(res.values[k]).mod(__P__);
}
delete a.values[k];
delete res.values[k];
}
}
for (let k in a.values) {
if (a.values[k].isZero()) delete a.values[k];
for (let k in res.values) {
if (res.values[k].isZero()) delete res.values[k];
}
return a;
return res;
} else if (a.type == "QEQ") {
a.a = canonize(ctx, a.a);
a.b = canonize(ctx, a.b);
a.c = canonize(ctx, a.c);
const res = {
type: "QEQ",
a: canonize(ctx, a.a),
b: canonize(ctx, a.b),
c: canonize(ctx, a.c)
};
return res;
} else {
return a;
}
return a;
}
function substitute(where, signal, equivalence) {
if (equivalence.type != "LINEARCOMBINATION") throw new Error("Equivalence must be a Linear Combination");
if (where.type == "LINEARCOMBINATION") {
if (!where.values[signal] || where.values[signal].isZero()) return where;
const coef = where.values[signal];
const res=clone(where);
const coef = res.values[signal];
for (let k in equivalence.values) {
if (k != signal) {
const v = coef.times(equivalence.values[k]).mod(__P__);
if (!where.values[k]) {
where.values[k]=v;
if (!res.values[k]) {
res.values[k]=v;
} else {
where.values[k]= where.values[k].add(v).mod(__P__);
res.values[k]= res.values[k].add(v).mod(__P__);
}
if (where.values[k].isZero()) delete where.values[k];
if (res.values[k].isZero()) delete res.values[k];
}
}
delete where.values[signal];
delete res.values[signal];
return res;
} else if (where.type == "QEQ") {
substitute(where.a, signal, equivalence);
substitute(where.b, signal, equivalence);
substitute(where.c, signal, equivalence);
const res = {
type: "QEQ",
a: substitute(where.a, signal, equivalence),
b: substitute(where.b, signal, equivalence),
c: substitute(where.c, signal, equivalence)
};
return res;
} else {
return where;
}
}