Browse Source

Tests added and Comparators

feature/witness_bin
Jordi Baylina 5 years ago
parent
commit
9d0b27a7e8
No known key found for this signature in database GPG Key ID: 7480C80C1BE43112
20 changed files with 268 additions and 122 deletions
  1. +0
    -0
      circuits/binsum.circom
  2. +27
    -0
      circuits/bitify.circom
  3. +55
    -0
      circuits/comparators.circom
  4. +0
    -67
      circuits/sha256/gates.circom
  5. +1
    -1
      circuits/sha256/sha256_2.circom
  6. +1
    -1
      circuits/sha256/sha256compression.circom
  7. +1
    -1
      circuits/sha256/sigmaplus.circom
  8. +1
    -1
      circuits/sha256/t1.circom
  9. +1
    -1
      circuits/sha256/t2.circom
  10. +16
    -0
      src/exec.js
  11. +14
    -2
      src/gencode.js
  12. +4
    -0
      test/circuits/isequal.circom
  13. +5
    -0
      test/circuits/iszero.circom
  14. +4
    -0
      test/circuits/lessthan.circom
  15. +2
    -2
      test/circuits/sum_test.circom
  16. +77
    -0
      test/comparators.js
  17. +22
    -0
      test/helpers/printsignal.js
  18. +0
    -4
      test/input_sum_test.json
  19. +2
    -42
      test/sha256.js
  20. +35
    -0
      test/sum.js

circuits/sha256/binsum.circom → circuits/binsum.circom


circuits/sha256/bitify.circom → circuits/bitify.circom

@ -17,6 +17,9 @@
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
include "comparators.circom";
template Num2Bits(n) {
signal input in;
signal output out[n];
@ -43,3 +46,27 @@ template Bits2Num(n) {
lc1 ==> out;
}
template Num2BitsNeg(n) {
signal input in;
signal output out[n];
var lc1=0;
component isZero;
isZero = IsZero();
var neg = n == 0 ? 0 : 2**n - in;
for (var i = 0; i<n; i++) {
out[i] <-- (neg >> i) & 1;
out[i] * (out[i] -1 ) === 0;
lc1 += out[i] * 2**i;
}
in ==> isZero.in;
lc1 + isZero.out * 2**n === 2**n - in;
}

+ 55
- 0
circuits/comparators.circom

@ -0,0 +1,55 @@
include "bitify.circom";
include "binsum.circom";
template IsZero() {
signal input in;
signal output out;
signal inv;
inv <-- in!=0 ? 1/in : 0;
out <== -in*inv +1;
in*out === 0;
}
template IsEqual() {
signal input in[2];
signal output out;
component isz = IsZero();
in[1] - in[0] ==> isz.in;
isz.out ==> out;
}
// N is the number of bits the input have.
// The MSF is the sign bit.
template LessThan(n) {
signal input in[2];
signal output out;
component num2Bits0;
component num2Bits1;
component adder;
adder = BinSum(n, 2);
num2Bits0 = Num2Bits(n);
num2Bits1 = Num2BitsNeg(n);
in[0] ==> num2Bits0.in;
in[1] ==> num2Bits1.in;
var i;
for (i=0;i<n;i++) {
num2Bits0.out[i] ==> adder.in[0][i];
num2Bits1.out[i] ==> adder.in[1][i];
}
adder.out[n-1] ==> out;
}

+ 0
- 67
circuits/sha256/gates.circom

@ -1,67 +0,0 @@
/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
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.
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 circom. If not, see <https://www.gnu.org/licenses/>.
*/
template XOR() {
signal input a;
signal input b;
signal output out;
out <== a + b - 2*a*b;
}
template AND() {
signal input a;
signal input b;
signal output out;
out <== a*b;
}
template OR() {
signal input a;
signal input b;
signal output out;
out <== a + b - a*b;
}
template NOT() {
signal input in;
signal output out;
out <== 1 + in - 2*in;
}
template NAND() {
signal input a;
signal input b;
signal output out;
out <== 1 - a*b;
}
template NOR() {
signal input a;
signal input b;
signal output out;
out <== a*b + 1 - a - b;
}

+ 1
- 1
circuits/sha256/sha256_2.circom

@ -18,7 +18,7 @@
*/
include "sha256compression.circom";
include "bitify.circom"
include "../bitify.circom"
template Sha256_2() {
signal input a;

+ 1
- 1
circuits/sha256/sha256compression.circom

@ -20,7 +20,7 @@
include "constants.circom";
include "t1.circom";
include "t2.circom";
include "binsum.circom";
include "../binsum.circom";
include "sigmaplus.circom";
template Sha256compression() {

+ 1
- 1
circuits/sha256/sigmaplus.circom

@ -17,7 +17,7 @@
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
include "binsum.circom"
include "../binsum.circom"
include "sigma.circom"
template SigmaPlus() {

+ 1
- 1
circuits/sha256/t1.circom

@ -17,7 +17,7 @@
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
include "binsum.circom";
include "../binsum.circom";
include "sigma.circom";
include "ch.circom";

+ 1
- 1
circuits/sha256/t2.circom

@ -17,7 +17,7 @@
along with circom. If not, see <https://www.gnu.org/licenses/>.
*/
include "binsum.circom";
include "../binsum.circom";
include "sigma.circom";
include "maj.circom"

+ 16
- 0
src/exec.js

@ -98,6 +98,8 @@ function exec(ctx, ast) {
return execGte(ctx, ast);
} else if (ast.op == "==") {
return execEq(ctx, ast);
} else if (ast.op == "!=") {
return execNeq(ctx, ast);
} else if (ast.op == "?") {
return execTerCon(ctx, ast);
} else {
@ -680,6 +682,20 @@ function execEq(ctx, ast) {
};
}
function execNeq(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.eq(b.value) ? bigInt(0) : bigInt(1)
};
}
function execBAnd(ctx, ast) {
const a = exec(ctx, ast.values[0]);

+ 14
- 2
src/gencode.js

@ -83,6 +83,8 @@ function gen(ctx, ast) {
return genGte(ctx, ast);
} else if (ast.op == "==") {
return genEq(ctx, ast);
} else if (ast.op == "!=") {
return genNeq(ctx, ast);
} else if (ast.op == "?") {
return genTerCon(ctx, ast);
} else {
@ -314,7 +316,9 @@ function genVariable(ctx, ast) {
if (ctx.error) return;
}
if (!v) {
return error(ctx, ast, "Invalid left operand");
}
if (v.type == "VARIABLE") {
return `ctx.getVar("${ast.name}",[${sels.join(",")}])`;
} else if (v.type == "SIGNAL") {
@ -530,7 +534,15 @@ function genEq(ctx, ast) {
if (ctx.error) return;
const b = gen(ctx, ast.values[1]);
if (ctx.error) return;
return `bigInt(${a}).eq(bigInt(${b})) ? 1 : 0`;
return `(bigInt(${a}).eq(bigInt(${b})) ? 1 : 0)`;
}
function genNeq(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}).eq(bigInt(${b})) ? 0 : 1)`;
}
function genUMinus(ctx, ast) {

+ 4
- 0
test/circuits/isequal.circom

@ -0,0 +1,4 @@
include "../../circuits/comparators.circom";
component main = IsEqual();

+ 5
- 0
test/circuits/iszero.circom

@ -0,0 +1,5 @@
include "../../circuits/comparators.circom";
component main = IsZero();

+ 4
- 0
test/circuits/lessthan.circom

@ -0,0 +1,4 @@
include "../../circuits/comparators.circom";
component main = LessThan(32);

+ 2
- 2
test/circuits/sum_test.circom

@ -1,5 +1,5 @@
include "../../circuits/sha256/bitify.circom"
include "../../circuits/sha256/binsum.circom"
include "../../circuits/bitify.circom"
include "../../circuits/binsum.circom"
template A() {
signal private input a;

+ 77
- 0
test/comparators.js

@ -0,0 +1,77 @@
const chai = require("chai");
const path = require("path");
const snarkjs = require("snarkjs");
const crypto = require("crypto");
const compiler = require("../index.js");
const assert = chai.assert;
describe("Sum test", () => {
it("Should create a iszero circuit", async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "iszero.circom"));
const circuit = new snarkjs.Circuit(cirDef);
let witness;
witness = circuit.calculateWitness({ "in": 111});
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = circuit.calculateWitness({ "in": 0 });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
});
it("Should create a isequal circuit", async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "isequal.circom"));
const circuit = new snarkjs.Circuit(cirDef);
let witness;
witness = circuit.calculateWitness({ "in[0]": "111", "in[1]": "222" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "444", "in[1]": "444" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
});
it("Should create a comparison", async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "lessthan.circom"));
const circuit = new snarkjs.Circuit(cirDef);
let witness;
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
});
});

+ 22
- 0
test/helpers/printsignal.js

@ -0,0 +1,22 @@
const snarkjs = require("snarkjs");
const bigInt = snarkjs.bigInt;
module.exports = function hexBits(cir, witness, sig, nBits) {
let v = bigInt(0);
for (let i=nBits-1; i>=0; i--) {
v = v.shiftLeft(1);
const name = sig+"["+i+"]";
const idx = cir.getSignalIdx(name);
const vbit = bigInt(witness[idx].toString());
if (vbit.equals(bigInt(1))) {
v = v.add(bigInt(1));
} else if (vbit.equals(bigInt(0))) {
v;
} else {
console.log("Not Binary: "+name);
}
}
return v.toString(16);
};

+ 0
- 4
test/input_sum_test.json

@ -1,4 +0,0 @@
{
"a": "111",
"b": "222"
}

+ 2
- 42
test/sha256.js

@ -8,51 +8,11 @@ const compiler = require("../index.js");
const assert = chai.assert;
const sha256 = require("./helpers/sha256");
const bigInt = require("big-integer");
function hexBits(cir, witness, sig, nBits) {
let v = bigInt(0);
for (let i=nBits-1; i>=0; i--) {
v = v.shiftLeft(1);
const name = sig+"["+i+"]";
const idx = cir.getSignalIdx(name);
const vbit = bigInt(witness[idx].toString());
if (vbit.equals(bigInt(1))) {
v = v.add(bigInt(1));
} else if (vbit.equals(bigInt(0))) {
v;
} else {
console.log("Not Binary: "+name);
}
}
return v.toString(16);
}
// const printSignal = require("./helpers/printsignal");
describe("SHA256 test", () => {
it("Should create a constant circuit", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "constants_test.circom"));
assert.equal(cirDef.nVars, 2);
const circuit = new snarkjs.Circuit(cirDef);
const witness = circuit.calculateWitness({ "in": "0xd807aa98" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt("0xd807aa98")));
});
it("Should create a sum circuit", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "sum_test.circom"));
assert.equal(cirDef.nVars, 101);
const circuit = new snarkjs.Circuit(cirDef);
const witness = circuit.calculateWitness({ "a": "111", "b": "222" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt("333")));
});
describe("SHA256 test", () => {
it("Should calculate a hash", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_2_test.circom"));
const circuit = new snarkjs.Circuit(cirDef);

+ 35
- 0
test/sum.js

@ -0,0 +1,35 @@
const chai = require("chai");
const path = require("path");
const snarkjs = require("snarkjs");
const crypto = require("crypto");
const compiler = require("../index.js");
const assert = chai.assert;
describe("Sum test", () => {
it("Should create a constant circuit", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "constants_test.circom"));
assert.equal(cirDef.nVars, 2);
const circuit = new snarkjs.Circuit(cirDef);
const witness = circuit.calculateWitness({ "in": "0xd807aa98" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt("0xd807aa98")));
});
it("Should create a sum circuit", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "sum_test.circom"));
assert.equal(cirDef.nVars, 101);
const circuit = new snarkjs.Circuit(cirDef);
const witness = circuit.calculateWitness({ "a": "111", "b": "222" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt("333")));
});
});

Loading…
Cancel
Save