Browse Source

Various small fixes

feature/witness_bin
Jordi Baylina 6 years ago
parent
commit
38fa024745
No known key found for this signature in database GPG Key ID: 7480C80C1BE43112
10 changed files with 243 additions and 2442 deletions
  1. +1
    -1
      package.json
  2. +12
    -2
      parser/jaz.jison
  3. +78
    -66
      parser/jaz.js
  4. +52
    -0
      src/exec.js
  5. +31
    -0
      src/gencode.js
  6. +24
    -2
      test/cases.js
  7. +12
    -0
      test/circuits/declareandistantiate.circom
  8. +19
    -0
      test/circuits/forvariables.circom
  9. +14
    -0
      test/circuits/mixvarsignal.circom
  10. +0
    -2371
      test/circuits/out.json

+ 1
- 1
package.json

@ -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"
} }
} }

+ 12
- 2
parser/jaz.jison

@ -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")) {

+ 78
- 66
parser/jaz.js
File diff suppressed because it is too large
View File


+ 52
- 0
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;

+ 31
- 0
src/gencode.js

@ -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;

+ 24
- 2
test/cases.js

@ -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
- 0
test/circuits/declareandistantiate.circom

@ -0,0 +1,12 @@
template A() {
signal a;
}
template B() {
component a[2] = A();
}
component main = B();

+ 19
- 0
test/circuits/forvariables.circom

@ -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
- 0
test/circuits/mixvarsignal.circom

@ -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();

+ 0
- 2371
test/circuits/out.json
File diff suppressed because it is too large
View File


Loading…
Cancel
Save