mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-06 18:56:40 +01:00
Various small fixes
This commit is contained in:
@@ -38,6 +38,6 @@
|
|||||||
"eslint": "^5.0.1",
|
"eslint": "^5.0.1",
|
||||||
"eslint-plugin-mocha": "^5.0.0",
|
"eslint-plugin-mocha": "^5.0.0",
|
||||||
"jison": "^0.4.18",
|
"jison": "^0.4.18",
|
||||||
"snarkjs": "0.1.6"
|
"snarkjs": "0.1.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ include { return 'include'; }
|
|||||||
\- { return '-'; }
|
\- { return '-'; }
|
||||||
\* { return '*'; }
|
\* { return '*'; }
|
||||||
\/ { return '/'; }
|
\/ { return '/'; }
|
||||||
|
\\ { return '\\'; }
|
||||||
\% { return '%'; }
|
\% { return '%'; }
|
||||||
\^ { return '^'; }
|
\^ { return '^'; }
|
||||||
\& { return '&'; }
|
\& { return '&'; }
|
||||||
@@ -118,7 +119,7 @@ include { return 'include'; }
|
|||||||
%left '<<' '>>'
|
%left '<<' '>>'
|
||||||
|
|
||||||
%left '+' '-'
|
%left '+' '-'
|
||||||
%left '*' '/' '%'
|
%left '*' '/' '\\' '%'
|
||||||
%left '**'
|
%left '**'
|
||||||
%right '++' '--' UMINUS UPLUS '!' '~'
|
%right '++' '--' UMINUS UPLUS '!' '~'
|
||||||
%left '.'
|
%left '.'
|
||||||
@@ -627,7 +628,7 @@ e7
|
|||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||||
let v = $3.value.greater(256) ? 256 : $3.value.value;
|
let v = $3.value.greater(256) ? 256 : $3.value.value;
|
||||||
$$ = {t1ype: "NUMBER", value: $1.value.shiftRight(v).and(__MASK__) };
|
$$ = {type: "NUMBER", value: $1.value.shiftRight(v).and(__MASK__) };
|
||||||
} else {
|
} else {
|
||||||
$$ = { type: "OP", op: ">>", values: [$1, $3] };
|
$$ = { type: "OP", op: ">>", values: [$1, $3] };
|
||||||
}
|
}
|
||||||
@@ -684,6 +685,15 @@ e5
|
|||||||
}
|
}
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
|
| e5 '\\' e4
|
||||||
|
{
|
||||||
|
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||||
|
$$ = { type: "NUMBER", value: ($1.value.divide($3.value)) };
|
||||||
|
} else {
|
||||||
|
$$ = { type: "OP", op: "\\", values: [$1, $3] };
|
||||||
|
}
|
||||||
|
setLines($$, @1, @3);
|
||||||
|
}
|
||||||
| e5 '%' e4
|
| e5 '%' e4
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
||||||
|
|||||||
144
parser/jaz.js
144
parser/jaz.js
File diff suppressed because one or more lines are too long
52
src/exec.js
52
src/exec.js
@@ -80,10 +80,16 @@ function exec(ctx, ast) {
|
|||||||
return execPlusPlusLeft(ctx, ast);
|
return execPlusPlusLeft(ctx, ast);
|
||||||
} else if (ast.op == "/") {
|
} else if (ast.op == "/") {
|
||||||
return execDiv(ctx, ast);
|
return execDiv(ctx, ast);
|
||||||
|
} else if (ast.op == "\\") {
|
||||||
|
return execIDiv(ctx, ast);
|
||||||
} else if (ast.op == "**") {
|
} else if (ast.op == "**") {
|
||||||
return execExp(ctx, ast);
|
return execExp(ctx, ast);
|
||||||
} else if (ast.op == "&") {
|
} else if (ast.op == "&") {
|
||||||
return execBAnd(ctx, ast);
|
return execBAnd(ctx, ast);
|
||||||
|
} else if (ast.op == "&&") {
|
||||||
|
return execAnd(ctx, ast);
|
||||||
|
} else if (ast.op == "||") {
|
||||||
|
return execOr(ctx, ast);
|
||||||
} else if (ast.op == "<<") {
|
} else if (ast.op == "<<") {
|
||||||
return execShl(ctx, ast);
|
return execShl(ctx, ast);
|
||||||
} else if (ast.op == ">>") {
|
} else if (ast.op == ">>") {
|
||||||
@@ -546,6 +552,8 @@ function execPin(ctx, ast) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function execFor(ctx, ast) {
|
function execFor(ctx, ast) {
|
||||||
|
|
||||||
|
ctx.scopes.push({});
|
||||||
exec(ctx, ast.init);
|
exec(ctx, ast.init);
|
||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
|
|
||||||
@@ -564,6 +572,7 @@ function execFor(ctx, ast) {
|
|||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ctx.scopes.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
function execWhile(ctx, ast) {
|
function execWhile(ctx, ast) {
|
||||||
@@ -722,6 +731,34 @@ function execBAnd(ctx, ast) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function execAnd(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" };
|
||||||
|
return {
|
||||||
|
type: "NUMBER",
|
||||||
|
value: (a.value.neq(0) && a.value.neq(0)) ? bigInt(1) : bigInt(0)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function execOr(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" };
|
||||||
|
return {
|
||||||
|
type: "NUMBER",
|
||||||
|
value: (a.value.neq(0) || a.value.neq(0)) ? bigInt(1) : bigInt(0)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function execShl(ctx, ast) {
|
function execShl(ctx, ast) {
|
||||||
const a = exec(ctx, ast.values[0]);
|
const a = exec(ctx, ast.values[0]);
|
||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
@@ -796,6 +833,21 @@ function execDiv(ctx, ast) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function execIDiv(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.divide(b.value)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function execAdd(ctx, ast) {
|
function execAdd(ctx, ast) {
|
||||||
const a = exec(ctx, ast.values[0]);
|
const a = exec(ctx, ast.values[0]);
|
||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
|
|||||||
@@ -67,8 +67,14 @@ function gen(ctx, ast) {
|
|||||||
return genExp(ctx, ast);
|
return genExp(ctx, ast);
|
||||||
} else if (ast.op == "/") {
|
} else if (ast.op == "/") {
|
||||||
return genDiv(ctx, ast);
|
return genDiv(ctx, ast);
|
||||||
|
} else if (ast.op == "\\") {
|
||||||
|
return genIDiv(ctx, ast);
|
||||||
} else if (ast.op == "&") {
|
} else if (ast.op == "&") {
|
||||||
return genBAnd(ctx, ast);
|
return genBAnd(ctx, ast);
|
||||||
|
} else if (ast.op == "&&") {
|
||||||
|
return genAnd(ctx, ast);
|
||||||
|
} else if (ast.op == "||") {
|
||||||
|
return genOr(ctx, ast);
|
||||||
} else if (ast.op == "<<") {
|
} else if (ast.op == "<<") {
|
||||||
return genShl(ctx, ast);
|
return genShl(ctx, ast);
|
||||||
} else if (ast.op == ">>") {
|
} else if (ast.op == ">>") {
|
||||||
@@ -457,6 +463,15 @@ function genDiv(ctx, ast) {
|
|||||||
return `bigInt(${a}).mul( bigInt(${b}).inverse(__P__) ).mod(__P__)`;
|
return `bigInt(${a}).mul( bigInt(${b}).inverse(__P__) ).mod(__P__)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function genIDiv(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}).div( bigInt(${b}))`;
|
||||||
|
}
|
||||||
|
|
||||||
function genExp(ctx, ast) {
|
function genExp(ctx, ast) {
|
||||||
const a = gen(ctx, ast.values[0]);
|
const a = gen(ctx, ast.values[0]);
|
||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
@@ -473,6 +488,22 @@ function genBAnd(ctx, ast) {
|
|||||||
return `bigInt(${a}).and(bigInt(${b})).and(__MASK__)`;
|
return `bigInt(${a}).and(bigInt(${b})).and(__MASK__)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function genAnd(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}).neq(bigInt(0)) && bigInt(${b}).neq(bigInt(0))) ? bigInt(1) : bigInt(0))`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function genOr(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}).neq(bigInt(0)) || bigInt(${b}).neq(bigInt(0))) ? bigInt(1) : bigInt(0))`;
|
||||||
|
}
|
||||||
|
|
||||||
function genShl(ctx, ast) {
|
function genShl(ctx, ast) {
|
||||||
const a = gen(ctx, ast.values[0]);
|
const a = gen(ctx, ast.values[0]);
|
||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
|
|||||||
@@ -1,14 +1,36 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("snarkjs");
|
const snarkjs = require("snarkjs");
|
||||||
const crypto = require("crypto");
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
const compiler = require("../index.js");
|
const compiler = require("../index.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
describe("Sum test", () => {
|
describe("Sum test", () => {
|
||||||
it("Should compile a code with an undefined if", async() => {
|
it("Should compile a code with an undefined if", async () => {
|
||||||
await compiler(path.join(__dirname, "circuits", "undefinedif.circom"));
|
await compiler(path.join(__dirname, "circuits", "undefinedif.circom"));
|
||||||
});
|
});
|
||||||
|
it("Should compile a code with vars inside a for", async () => {
|
||||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "forvariables.circom"));
|
||||||
|
|
||||||
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
const witness = circuit.calculateWitness({ "in": 111});
|
||||||
|
assert(witness[0].equals(bigInt(1)));
|
||||||
|
assert(witness[1].equals(bigInt(114)));
|
||||||
|
assert(witness[2].equals(bigInt(111)));
|
||||||
|
|
||||||
|
});
|
||||||
|
it("Should compile a code with an undefined if", async () => {
|
||||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "mixvarsignal.circom"));
|
||||||
|
|
||||||
|
const circuit = new snarkjs.Circuit(cirDef);
|
||||||
|
|
||||||
|
const witness = circuit.calculateWitness({ "i": 111});
|
||||||
|
assert(witness[0].equals(bigInt(1)));
|
||||||
|
assert(witness[1].equals(bigInt(111)));
|
||||||
|
assert(witness[2].equals(bigInt(111)));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
12
test/circuits/declareandistantiate.circom
Normal file
12
test/circuits/declareandistantiate.circom
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template A() {
|
||||||
|
signal a;
|
||||||
|
}
|
||||||
|
|
||||||
|
template B() {
|
||||||
|
component a[2] = A();
|
||||||
|
}
|
||||||
|
|
||||||
|
component main = B();
|
||||||
19
test/circuits/forvariables.circom
Normal file
19
test/circuits/forvariables.circom
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
template A() {
|
||||||
|
signal input in;
|
||||||
|
signal output out;
|
||||||
|
|
||||||
|
var acc = 0;
|
||||||
|
for (var i=0; i<3; i++) {
|
||||||
|
if (i==1) {
|
||||||
|
var accIn = 0;
|
||||||
|
for (var j=0; j<3; j++) {
|
||||||
|
accIn= accIn+1;
|
||||||
|
}
|
||||||
|
acc = acc + accIn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out <== in + acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
component main = A();
|
||||||
14
test/circuits/mixvarsignal.circom
Normal file
14
test/circuits/mixvarsignal.circom
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
template X() {
|
||||||
|
signal input i;
|
||||||
|
signal output out;
|
||||||
|
|
||||||
|
var r = 0;
|
||||||
|
for (var n=0; n<i; n++) {
|
||||||
|
r++;
|
||||||
|
}
|
||||||
|
|
||||||
|
i === r;
|
||||||
|
out <== r;
|
||||||
|
}
|
||||||
|
|
||||||
|
component main = X();
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user