diff --git a/README.md b/README.md index cf40564..cad5f90 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,10 @@ In particular, it is designed to work in [zksnarks JavaScript library](https://g ## Usage +### Tutorial + +A good starting point [is this tutorial](https://iden3.io/blog/circom-and-snarkjs-tutorial2.html) + ### First circuit Creation of a circuit. This is an example of a NAND door: @@ -254,6 +258,11 @@ component main = Adder(); In this example we have shown how to design a top-down circuit with many subcircuits and how to connect them together. One can also see that auxiliary functions to do specific computations can be created. +### More examples. + +You can find more examples in this library of basic circits [circomlib](https://github.com/iden3/circomlib) + + ## License Circom is part of the iden3 project copyright 2018 0KIMS association and published with GPL-3 license. Please check the COPYING file for more details. diff --git a/circuit.json b/circuit.json new file mode 100644 index 0000000..fccaf78 --- /dev/null +++ b/circuit.json @@ -0,0 +1,44 @@ +{ + "mainCode": "{\n}\n", + "signalName2Idx": { + "one": 0, + "main.out": 1 + }, + "components": [ + { + "name": "main", + "params": {}, + "template": "A", + "inputSignals": 0 + } + ], + "componentName2Idx": { + "main": 0 + }, + "signals": [ + { + "names": [ + "one" + ], + "triggerComponents": [] + }, + { + "names": [ + "main.out" + ], + "triggerComponents": [] + } + ], + "constraints": [], + "templates": { + "A": "function(ctx) {\n ctx.setSignal(\"out\", [], \"3\");\n ctx.assert(ctx.getSignal(\"out\", []), \"3\");\n}\n" + }, + "functions": {}, + "nPrvInputs": 0, + "nPubInputs": 0, + "nInputs": 0, + "nOutputs": 0, + "nVars": 1, + "nConstants": 1, + "nSignals": 2 +} \ No newline at end of file diff --git a/circuits/binsum.circom b/circuits/binsum.circom deleted file mode 100644 index 3783e26..0000000 --- a/circuits/binsum.circom +++ /dev/null @@ -1,93 +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 . -*/ - -/* - -Binary Sum -========== - -This component creates a binary sum componet of ops operands and n bits each operand. - -e is Number of carries: Depends on the number of operands in the input. - -Main Constraint: - in[0][0] * 2^0 + in[0][1] * 2^1 + ..... + in[0][n-1] * 2^(n-1) + - + in[1][0] * 2^0 + in[1][1] * 2^1 + ..... + in[1][n-1] * 2^(n-1) + - + .. - + in[ops-1][0] * 2^0 + in[ops-1][1] * 2^1 + ..... + in[ops-1][n-1] * 2^(n-1) + - === - out[0] * 2^0 + out[1] * 2^1 + + out[n+e-1] *2(n+e-1) - -To waranty binary outputs: - - out[0] * (out[0] - 1) === 0 - out[1] * (out[0] - 1) === 0 - . - . - . - out[n+e-1] * (out[n+e-1] - 1) == 0 - - */ - - -/* - This function calculates the number of extra bits in the output to do the full sum. - */ - -function nbits(a) { - var n = 1; - var r = 0; - while (n-1> k) & 1; - - // Ensure out is binary - out[k] * (out[k] - 1) === 0; - - lout += out[k] * 2**k; - } - - // Ensure the sum; - - lin === lout; -} diff --git a/circuits/bitify.circom b/circuits/bitify.circom deleted file mode 100644 index b701f93..0000000 --- a/circuits/bitify.circom +++ /dev/null @@ -1,72 +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 . -*/ - -include "comparators.circom"; - - -template Num2Bits(n) { - signal input in; - signal output out[n]; - var lc1=0; - - for (var i = 0; i> i) & 1; - out[i] * (out[i] -1 ) === 0; - lc1 += out[i] * 2**i; - } - - lc1 === in; - -} - -template Bits2Num(n) { - signal input in[n]; - signal output out; - var lc1=0; - - for (var i = 0; i 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> i) & 1; - out[i] * (out[i] -1 ) === 0; - lc1 += out[i] * 2**i; - } - - in ==> isZero.in; - - - - lc1 + isZero.out * 2**n === 2**n - in; -} diff --git a/circuits/comparators.circom b/circuits/comparators.circom deleted file mode 100644 index 732bd6b..0000000 --- a/circuits/comparators.circom +++ /dev/null @@ -1,55 +0,0 @@ -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 adder.in[0][i]; - num2Bits1.out[i] ==> adder.in[1][i]; - } - - adder.out[n-1] ==> out; -} diff --git a/circuits/gates.circom b/circuits/gates.circom deleted file mode 100644 index a1fe69a..0000000 --- a/circuits/gates.circom +++ /dev/null @@ -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 . -*/ - -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; -} - - diff --git a/circuits/multiplexer.circom b/circuits/multiplexer.circom deleted file mode 100644 index fc66406..0000000 --- a/circuits/multiplexer.circom +++ /dev/null @@ -1,93 +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 . -*/ - -// --> Assignation without constraint -// <-- Assignation without constraint -// === Constraint -// <== Assignation with constraint -// ==> Assignation with constraint -// All variables are members of the field F[p] -// https://github.com/zcash-hackworks/sapling-crypto -// https://github.com/ebfull/bellman - -/* -function log2(a) { - if (a==0) { - return 0; - } - let n = 1; - let r = 1; - while (n success; - success * (success -1) === 0; -} - - -template Multiplexor(wIn, nIn) { - signal input inp[nIn][wIn]; - signal input sel; - signal output out[wIn]; - component Decoder(nIn) dec; - component EscalarProduct(nIn) ep[wIn]; - sel ==> dec.inp; - for (var j=0; j ep[j].in1[k]; - dec.out[k] ==> ep[j].in2[k]; - } - ep[j].out ==> out[j]; - } - dec.success === 1; -} - -component Multiplexor(8,3) main; - - diff --git a/circuits/sha256/ch.circom b/circuits/sha256/ch.circom deleted file mode 100644 index 5804ae8..0000000 --- a/circuits/sha256/ch.circom +++ /dev/null @@ -1,46 +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 . -*/ - -/* Ch - -000 0 -001 1 -010 0 -011 1 -100 0 -101 0 -110 1 -111 1 - -out = a&b ^ (!a)&c => - -out = a*(b-c) + c - -*/ - -template Ch(n) { - signal input a[n]; - signal input b[n]; - signal input c[n]; - signal output out[n]; - - for (var k=0; k. -*/ - -template H(x) { - signal output out[32]; - var c = [0x6a09e667, - 0xbb67ae85, - 0x3c6ef372, - 0xa54ff53a, - 0x510e527f, - 0x9b05688c, - 0x1f83d9ab, - 0x5be0cd19]; - - for (var i=0; i<32; i++) { - out[i] <== (c[x] >> i) & 1; - } -} - -template K(x) { - signal output out[32]; - var c = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 - ]; - - for (var i=0; i<32; i++) { - out[i] <== (c[x] >> i) & 1; - } -} diff --git a/circuits/sha256/main.circom b/circuits/sha256/main.circom deleted file mode 100644 index fbf2434..0000000 --- a/circuits/sha256/main.circom +++ /dev/null @@ -1,34 +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 . -*/ - -include "sha256_2.jaz"; - -template Main() { - signal private input a; - signal private input b; - signal output out; - - component sha256_2 = SHA256_2(); - - sha256_2.a <== a; - sha256_2.b <== a; - out <== sha256_2.out; -} - -component main = Main(); diff --git a/circuits/sha256/maj.circom b/circuits/sha256/maj.circom deleted file mode 100644 index ee53687..0000000 --- a/circuits/sha256/maj.circom +++ /dev/null @@ -1,44 +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 . -*/ - -/* Maj function for sha256 - -out = a&b ^ a&c ^ b&c => - -out = a*b + a*c + b*c - 2*a*b*c => - -out = a*( b + c - 2*b*c ) + b*c => - -mid = b*c -out = a*( b + c - 2*mid ) + mid - -*/ - -template Maj(n) { - signal input a[n]; - signal input b[n]; - signal input c[n]; - signal output out[n]; - signal mid[n]; - - for (var k=0; k. -*/ - -template RotR(n, r) { - signal input in[n]; - signal output out[n]; - - for (var i=0; i. -*/ - -include "sha256compression.circom"; -include "../bitify.circom" - -template Sha256_2() { - signal input a; - signal input b; - signal output out; - - component bits2num = Bits2Num(216); - component num2bits[2]; - - num2bits[0] = Num2Bits(216); - num2bits[1] = Num2Bits(216); - - num2bits[0].in <== a; - num2bits[1].in <== b; - - component sha256compression = Sha256compression() ; - - var i; - - for (i=0; i<216; i++) { - sha256compression.inp[i] <== num2bits[0].out[215-i]; - sha256compression.inp[i+216] <== num2bits[1].out[215-i]; - } - - sha256compression.inp[432] <== 1; - - for (i=433; i<503; i++) { - sha256compression.inp[i] <== 0; - } - - sha256compression.inp[503] <== 1; - sha256compression.inp[504] <== 1; - sha256compression.inp[505] <== 0; - sha256compression.inp[506] <== 1; - sha256compression.inp[507] <== 1; - sha256compression.inp[508] <== 0; - sha256compression.inp[509] <== 0; - sha256compression.inp[510] <== 0; - sha256compression.inp[511] <== 0; - - for (i=0; i<216; i++) { - bits2num.in[i] <== sha256compression.out[255-i]; - } - - out <== bits2num.out; -} diff --git a/circuits/sha256/sha256compression.circom b/circuits/sha256/sha256compression.circom deleted file mode 100644 index 66e041b..0000000 --- a/circuits/sha256/sha256compression.circom +++ /dev/null @@ -1,164 +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 . -*/ - -include "constants.circom"; -include "t1.circom"; -include "t2.circom"; -include "../binsum.circom"; -include "sigmaplus.circom"; - -template Sha256compression() { - signal input inp[512]; - signal output out[256]; - signal a[65][32]; - signal b[65][32]; - signal c[65][32]; - signal d[65][32]; - signal e[65][32]; - signal f[65][32]; - signal g[65][32]; - signal h[65][32]; - signal w[64][32]; - - var i; - - component sigmaPlus[48]; - for (i=0; i<48; i++) sigmaPlus[i] = SigmaPlus(); - - component ct_k[64]; - for (i=0; i<64; i++) ct_k[i] = K(i); - - component ha0 = H(0); - component hb0 = H(1); - component hc0 = H(2); - component hd0 = H(3); - component he0 = H(4); - component hf0 = H(5); - component hg0 = H(6); - component hh0 = H(7); - - component t1[64]; - for (i=0; i<64; i++) t1[i] = T1(); - - component t2[64]; - for (i=0; i<64; i++) t2[i] = T2(); - - component suma[64]; - for (i=0; i<64; i++) suma[i] = BinSum(32, 2); - - component sume[64]; - for (i=0; i<64; i++) sume[i] = BinSum(32, 2); - - component fsum[8]; - for (i=0; i<8; i++) fsum[i] = BinSum(32, 2); - - var k; - var t; - - for (t=0; t<64; t++) { - if (t<16) { - for (k=0; k<32; k++) { - w[t][k] <== inp[t*32+31-k]; - } - } else { - for (k=0; k<32; k++) { - sigmaPlus[t-16].in2[k] <== w[t-2][k]; - sigmaPlus[t-16].in7[k] <== w[t-7][k]; - sigmaPlus[t-16].in15[k] <== w[t-15][k]; - sigmaPlus[t-16].in16[k] <== w[t-16][k]; - w[t][k] <== sigmaPlus[t-16].out[k]; - } - } - } - - for (k=0; k<32; k++ ) { - a[0][k] <== ha0.out[k] - b[0][k] <== hb0.out[k] - c[0][k] <== hc0.out[k] - d[0][k] <== hd0.out[k] - e[0][k] <== he0.out[k] - f[0][k] <== hf0.out[k] - g[0][k] <== hg0.out[k] - h[0][k] <== hh0.out[k] - } - - for (t = 0; t<64; t++) { - for (k=0; k<32; k++) { - t1[t].h[k] <== h[t][k]; - t1[t].e[k] <== e[t][k]; - t1[t].f[k] <== f[t][k]; - t1[t].g[k] <== g[t][k]; - t1[t].k[k] <== ct_k[t].out[k]; - t1[t].w[k] <== w[t][k]; - - t2[t].a[k] <== a[t][k]; - t2[t].b[k] <== b[t][k]; - t2[t].c[k] <== c[t][k]; - } - - for (k=0; k<32; k++) { - sume[t].in[0][k] <== d[t][k]; - sume[t].in[1][k] <== t1[t].out[k]; - - suma[t].in[0][k] <== t1[t].out[k]; - suma[t].in[1][k] <== t2[t].out[k]; - } - - for (k=0; k<32; k++) { - h[t+1][k] <== g[t][k]; - g[t+1][k] <== f[t][k]; - f[t+1][k] <== e[t][k]; - e[t+1][k] <== sume[t].out[k]; - d[t+1][k] <== c[t][k]; - c[t+1][k] <== b[t][k]; - b[t+1][k] <== a[t][k]; - a[t+1][k] <== suma[t].out[k]; - } - } - - for (k=0; k<32; k++) { - fsum[0].in[0][k] <== ha0.out[k]; - fsum[0].in[1][k] <== a[64][k]; - fsum[1].in[0][k] <== hb0.out[k]; - fsum[1].in[1][k] <== b[64][k]; - fsum[2].in[0][k] <== hc0.out[k]; - fsum[2].in[1][k] <== c[64][k]; - fsum[3].in[0][k] <== hd0.out[k]; - fsum[3].in[1][k] <== d[64][k]; - fsum[4].in[0][k] <== he0.out[k]; - fsum[4].in[1][k] <== e[64][k]; - fsum[5].in[0][k] <== hf0.out[k]; - fsum[5].in[1][k] <== f[64][k]; - fsum[6].in[0][k] <== hg0.out[k]; - fsum[6].in[1][k] <== g[64][k]; - fsum[7].in[0][k] <== hh0.out[k]; - fsum[7].in[1][k] <== h[64][k]; - } - - for (k=0; k<32; k++) { - out[31-k] <== fsum[0].out[k]; - out[32+31-k] <== fsum[1].out[k]; - out[64+31-k] <== fsum[2].out[k]; - out[96+31-k] <== fsum[3].out[k]; - out[128+31-k] <== fsum[4].out[k]; - out[160+31-k] <== fsum[5].out[k]; - out[192+31-k] <== fsum[6].out[k]; - out[224+31-k] <== fsum[7].out[k]; - } -} diff --git a/circuits/sha256/shift.circom b/circuits/sha256/shift.circom deleted file mode 100644 index bdff3fd..0000000 --- a/circuits/sha256/shift.circom +++ /dev/null @@ -1,32 +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 . -*/ - -template ShR(n, r) { - signal input in[n]; - signal output out[n]; - - for (var i=0; i= n) { - out[i] <== 0; - } else { - out[i] <== in[ i+r ]; - } - } -} - diff --git a/circuits/sha256/sigma.circom b/circuits/sha256/sigma.circom deleted file mode 100644 index 3baa646..0000000 --- a/circuits/sha256/sigma.circom +++ /dev/null @@ -1,68 +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 . -*/ - -include "xor3.circom"; -include "rotate.circom"; -include "shift.circom"; - -template SmallSigma(ra, rb, rc) { - signal input in[32]; - signal output out[32]; - - component xor3 = Xor3(32); - - component rota = RotR(32, ra); - component rotb = RotR(32, rb); - component shrc = ShR(32, rc); - - for (var k=0; k<32; k++) { - rota.in[k] <== in[k]; - rotb.in[k] <== in[k]; - shrc.in[k] <== in[k]; - - xor3.a[k] <== rota.out[k]; - xor3.b[k] <== rotb.out[k]; - xor3.c[k] <== shrc.out[k]; - - out[k] <== xor3.out[k]; - } -} - -template BigSigma(ra, rb, rc) { - signal input in[32]; - signal output out[32]; - - component xor3 = Xor3(32); - - component rota = RotR(32, ra); - component rotb = RotR(32, rb); - component rotc = RotR(32, rc); - - for (var k=0; k<32; k++) { - rota.in[k] <== in[k]; - rotb.in[k] <== in[k]; - rotc.in[k] <== in[k]; - - xor3.a[k] <== rota.out[k]; - xor3.b[k] <== rotb.out[k]; - xor3.c[k] <== rotc.out[k]; - - out[k] <== xor3.out[k]; - } -} diff --git a/circuits/sha256/sigmaplus.circom b/circuits/sha256/sigmaplus.circom deleted file mode 100644 index ec5a457..0000000 --- a/circuits/sha256/sigmaplus.circom +++ /dev/null @@ -1,45 +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 . -*/ - -include "../binsum.circom" -include "sigma.circom" - -template SigmaPlus() { - signal input in2[32]; - signal input in7[32]; - signal input in15[32]; - signal input in16[32]; - signal output out[32]; - - component sum = BinSum(32, 4); - component sigma1 = SmallSigma(17,19,10); - component sigma0 = SmallSigma(7, 18, 3); - - for (var k=0; k<32; k++) { - sigma1.in[k] <== in2[k]; - sigma0.in[k] <== in15[k]; - - sum.in[0][k] <== sigma1.out[k]; - sum.in[1][k] <== in7[k]; - sum.in[2][k] <== sigma0.out[k]; - sum.in[3][k] <== in16[k]; - - out[k] <== sum.out[k]; - } -} diff --git a/circuits/sha256/t1.circom b/circuits/sha256/t1.circom deleted file mode 100644 index 28caed6..0000000 --- a/circuits/sha256/t1.circom +++ /dev/null @@ -1,52 +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 . -*/ - -include "../binsum.circom"; -include "sigma.circom"; -include "ch.circom"; - -template T1() { - signal input h[32]; - signal input e[32]; - signal input f[32]; - signal input g[32]; - signal input k[32]; - signal input w[32]; - signal output out[32]; - - component sum = BinSum(32, 5); - component ch = Ch(32); - - component bigsigma1 = BigSigma(6, 11, 25); - - for (var ki=0; ki<32; ki++) { - bigsigma1.in[ki] <== e[ki]; - ch.a[ki] <== e[ki]; - ch.b[ki] <== f[ki]; - ch.c[ki] <== g[ki] - - sum.in[0][ki] <== h[ki]; - sum.in[1][ki] <== bigsigma1.out[ki]; - sum.in[2][ki] <== ch.out[ki]; - sum.in[3][ki] <== k[ki]; - sum.in[4][ki] <== w[ki]; - - out[ki] <== sum.out[ki]; - } -} diff --git a/circuits/sha256/t2.circom b/circuits/sha256/t2.circom deleted file mode 100644 index 54de837..0000000 --- a/circuits/sha256/t2.circom +++ /dev/null @@ -1,47 +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 . -*/ - -include "../binsum.circom"; -include "sigma.circom"; -include "maj.circom" - -template T2() { - signal input a[32]; - signal input b[32]; - signal input c[32]; - signal output out[32]; - - component sum = BinSum(32, 2); - - component bigsigma0 = BigSigma(2, 13, 22); - component maj = Maj(32); - - for (var k=0; k<32; k++) { - - bigsigma0.in[k] <== a[k]; - maj.a[k] <== a[k]; - maj.b[k] <== b[k]; - maj.c[k] <== c[k]; - - sum.in[0][k] <== bigsigma0.out[k]; - sum.in[1][k] <== maj.out[k]; - - out[k] <== sum.out[k]; - } -} diff --git a/circuits/sha256/xor3.circom b/circuits/sha256/xor3.circom deleted file mode 100644 index 9bbe76c..0000000 --- a/circuits/sha256/xor3.circom +++ /dev/null @@ -1,44 +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 . -*/ - -/* Xor3 function for sha256 - -out = a ^ b ^ c => - -out = a+b+c - 2*a*b - 2*a*c - 2*b*c + 4*a*b*c => - -out = a*( 1 - 2*b - 2*c + 4*b*c ) + b + c - 2*b*c => - -mid = b*c -out = a*( 1 - 2*b -2*c + 4*mid ) + b + c - 2 * mid - -*/ - -template Xor3(n) { - signal input a[n]; - signal input b[n]; - signal input c[n]; - signal output out[n]; - signal mid[n]; - - for (var k=0; k. -*/ - - -template toBin(n) { - signal input inp; - signal output out[n]; - var lc1=0; - - for (var i = 0; i> i) & 1; - out[i] * (out[i] -1 ) === 0; - lc1 += out[i] * 2**i; - } - - lc1 === inp; - -} - - -component toBin(3) main; diff --git a/src/exec.js b/src/exec.js index 60a7d9d..cc9c036 100644 --- a/src/exec.js +++ b/src/exec.js @@ -158,7 +158,8 @@ function error(ctx, ast, errStr) { }, errStr: errStr, errFile: ctx.fileName, - ast: ast + ast: ast, + message: errStr }; } @@ -622,6 +623,7 @@ function execVarAssignement(ctx, ast) { if ((typeof(num) != "object")||(num == null)) return error(ctx, ast, "Variable not defined"); if (num.type == "COMPONENT") return execInstantiateComponet(ctx, v, ast.values[1]); +// if (num.type == "SIGNAL") return error(ctx, ast, "Cannot assign to a signal with `=` use <-- or <== ops"); const res = exec(ctx, ast.values[1]); if (ctx.error) return; diff --git a/src/genOptCode.js b/src/genOptCode.js new file mode 100644 index 0000000..62411f4 --- /dev/null +++ b/src/genOptCode.js @@ -0,0 +1,70 @@ + + +module.exports = genOpt; + + +function genOpt(ctx, ast) { + if (ast.type == "OP") { + if (ast.op == "=") { + return genOptVarAssignement(ctx, ast); + } else { + error(ctx, ast, "GENOPT -> Invalid operation: " + ast.op); + } + } else if (ast.type == "TEMPLATEDEF") { + return genOptTemplateDef(ctx, ast); + } else { + error(ctx, ast, "GENOPT -> Invalid AST node type: " + ast.type); + } +} + +function error(ctx, ast, errStr) { + ctx.error = { + pos: { + first_line: ast.first_line, + first_column: ast.first_column, + last_line: ast.last_line, + last_column: ast.last_column + }, + errStr: errStr, + errFile: ctx.fileName, + ast: ast + }; +} + + +function genOptTemplateDef(ctx, ast) { + if (ctx.templates[ast.name]) { + return error(ctx, ast, "Template name already exists: "+ast.name); + } + ctx.templates[ast.name] = { + type: "TEMPLATE", + params: ast.params, + block: ast.block, + fileName: ctx.fileName, + filePath: ctx.filePath + }; +} + +function genOptVarAssignement(ctx, ast) { + let varName; + if (ast.values[0].type == "DECLARE") { + varName = genOptCode(ctx, ast.values[0]); + if (ctx.error) return; + } else { + varName = ast.values[0]; + } + const varContent = getScope(ctx, varName.name, varName.selectors); + if (ctx.error) return; + + if ((typeof(varContent) != "object")||(varContent == null)) return error(ctx, ast, "Variable not defined"); + + if (varContent.type == "COMPONENT") return genOptInstantiateComponet(ctx, varName, ast.values[1]); + if (varContent.type == "SIGNAL") return error(ctx, ast, "Cannot assig to a signal with `=` use <-- or <== ops"); + + const res = genOpt(ctx, ast.values[1]); + if (ctx.error) return; + + setScope(ctx, varName.name, varName.selectors, res); + + return v; +} diff --git a/src/gencode.js b/src/gencode.js index 5321d56..3bff316 100644 --- a/src/gencode.js +++ b/src/gencode.js @@ -143,7 +143,8 @@ function error(ctx, ast, errStr) { last_column: ast.last_column }, errStr: errStr, - ast: ast + ast: ast, + message: errStr }; } diff --git a/test/cases.js b/test/cases.js index 9e94bfc..f5ec4c3 100644 --- a/test/cases.js +++ b/test/cases.js @@ -8,6 +8,17 @@ const compiler = require("../index.js"); const assert = chai.assert; +async function assertThrowsAsync(fn, regExp) { + let f = () => {}; + try { + await fn(); + } catch(e) { + f = () => { throw e; }; + } finally { + assert.throws(f, regExp); + } +} + describe("Sum test", () => { it("Should compile a code with an undefined if", async () => { await compiler(path.join(__dirname, "circuits", "undefinedif.circom")); @@ -33,4 +44,9 @@ describe("Sum test", () => { assert(witness[1].equals(bigInt(111))); assert(witness[2].equals(bigInt(111))); }); +// it("Should assign signal ERROR", async () => { +// await assertThrowsAsync(async () => { +// await compiler(path.join(__dirname, "circuits", "assignsignal.circom")); +// }, /Cannot assign to a signal .*/); +// }); }); diff --git a/test/circuits/assignsignal.circom b/test/circuits/assignsignal.circom new file mode 100644 index 0000000..ffe5f47 --- /dev/null +++ b/test/circuits/assignsignal.circom @@ -0,0 +1,7 @@ +template A() { + signal output out; + + out = 3; // This is an error that compile should detect +} + +component main = A(); diff --git a/test/circuits/constants_test.circom b/test/circuits/constants_test.circom deleted file mode 100644 index 61d392d..0000000 --- a/test/circuits/constants_test.circom +++ /dev/null @@ -1,18 +0,0 @@ -include "../../circuits/sha256/constants.circom" - -template A() { - signal input in; - component h0; - h0 = K(8); - - var lc = 0; - var e = 1; - for (var i=0; i<32; i++) { - lc = lc + e*h0.out[i]; - e *= 2; - } - - lc === in; -} - -component main = A(); diff --git a/test/circuits/isequal.circom b/test/circuits/isequal.circom deleted file mode 100644 index c14d506..0000000 --- a/test/circuits/isequal.circom +++ /dev/null @@ -1,4 +0,0 @@ - -include "../../circuits/comparators.circom"; - -component main = IsEqual(); diff --git a/test/circuits/iszero.circom b/test/circuits/iszero.circom deleted file mode 100644 index 0ca0589..0000000 --- a/test/circuits/iszero.circom +++ /dev/null @@ -1,5 +0,0 @@ - - -include "../../circuits/comparators.circom"; - -component main = IsZero(); diff --git a/test/circuits/lessthan.circom b/test/circuits/lessthan.circom deleted file mode 100644 index 63944f2..0000000 --- a/test/circuits/lessthan.circom +++ /dev/null @@ -1,4 +0,0 @@ - -include "../../circuits/comparators.circom"; - -component main = LessThan(32); diff --git a/test/circuits/sha256_2_test.circom b/test/circuits/sha256_2_test.circom deleted file mode 100644 index 855423b..0000000 --- a/test/circuits/sha256_2_test.circom +++ /dev/null @@ -1,15 +0,0 @@ -include "../../circuits/sha256/sha256_2.circom"; - -template Main() { - signal private input a; - signal private input b; - signal output out; - - component sha256_2 = Sha256_2(); - - sha256_2.a <== a; - sha256_2.b <== b; - out <== sha256_2.out; -} - -component main = Main(); diff --git a/test/circuits/sum_test.circom b/test/circuits/sum_test.circom deleted file mode 100644 index a8b062b..0000000 --- a/test/circuits/sum_test.circom +++ /dev/null @@ -1,26 +0,0 @@ -include "../../circuits/bitify.circom" -include "../../circuits/binsum.circom" - -template A() { - signal private input a; - signal input b; - signal output out; - - component n2ba = Num2Bits(32); - component n2bb = Num2Bits(32); - component sum = BinSum(32,2); - component b2n = Bits2Num(32); - - n2ba.in <== a; - n2bb.in <== b; - - for (var i=0; i<32; i++) { - sum.in[0][i] <== n2ba.out[i]; - sum.in[1][i] <== n2bb.out[i]; - b2n.in[i] <== sum.out[i]; - } - - out <== b2n.out; -} - -component main = A(); diff --git a/test/comparators.js b/test/comparators.js deleted file mode 100644 index 0e6f144..0000000 --- a/test/comparators.js +++ /dev/null @@ -1,77 +0,0 @@ -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))); - }); -}); diff --git a/test/helpers/printsignal.js b/test/helpers/printsignal.js deleted file mode 100644 index 796274d..0000000 --- a/test/helpers/printsignal.js +++ /dev/null @@ -1,22 +0,0 @@ - -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); -}; diff --git a/test/helpers/sha256.js b/test/helpers/sha256.js deleted file mode 100644 index ec58ee1..0000000 --- a/test/helpers/sha256.js +++ /dev/null @@ -1,178 +0,0 @@ -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -/* SHA-256 (FIPS 180-4) implementation in JavaScript (c) Chris Veness 2002-2017 */ -/* MIT Licence */ -/* www.movable-type.co.uk/scripts/sha256.html */ -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -'use strict'; - - -/** - * SHA-256 hash function reference implementation. - * - * This is an annotated direct implementation of FIPS 180-4, without any optimisations. It is - * intended to aid understanding of the algorithm rather than for production use. - * - * While it could be used where performance is not critical, I would recommend using the ‘Web - * Cryptography API’ (developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest) for the browser, - * or the ‘crypto’ library (nodejs.org/api/crypto.html#crypto_class_hash) in Node.js. - * - * See csrc.nist.gov/groups/ST/toolkit/secure_hashing.html - * csrc.nist.gov/groups/ST/toolkit/examples.html - */ -class Sha256 { - - /** - * Generates SHA-256 hash of string. - * - * @param {string} msg - (Unicode) string to be hashed. - * @param {Object} [options] - * @param {string} [options.msgFormat=string] - Message format: 'string' for JavaScript string - * (gets converted to UTF-8 for hashing); 'hex-bytes' for string of hex bytes ('616263' ≡ 'abc') . - * @param {string} [options.outFormat=hex] - Output format: 'hex' for string of contiguous - * hex bytes; 'hex-w' for grouping hex bytes into groups of (4 byte / 8 character) words. - * @returns {string} Hash of msg as hex character string. - */ - static hash(msg, options) { - const defaults = { msgFormat: 'string', outFormat: 'hex' }; - const opt = Object.assign(defaults, options); - - // note use throughout this routine of 'n >>> 0' to coerce Number 'n' to unsigned 32-bit integer - - switch (opt.msgFormat) { - default: // default is to convert string to UTF-8, as SHA only deals with byte-streams - case 'string': msg = utf8Encode(msg); break; - case 'hex-bytes':msg = hexBytesToString(msg); break; // mostly for running tests - } - - // constants [§4.2.2] - const K = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 ]; - - // initial hash value [§5.3.3] - const H = [ - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; - - // PREPROCESSING [§6.2.1] - - msg += String.fromCharCode(0x80); // add trailing '1' bit (+ 0's padding) to string [§5.1.1] - - // convert string msg into 512-bit blocks (array of 16 32-bit integers) [§5.2.1] - const l = msg.length/4 + 2; // length (in 32-bit integers) of msg + ‘1’ + appended length - const N = Math.ceil(l/16); // number of 16-integer (512-bit) blocks required to hold 'l' ints - const M = new Array(N); // message M is N×16 array of 32-bit integers - - for (let i=0; i>> 32, but since JS converts - // bitwise-op args to 32 bits, we need to simulate this by arithmetic operators - const lenHi = ((msg.length-1)*8) / Math.pow(2, 32); - const lenLo = ((msg.length-1)*8) >>> 0; - M[N-1][14] = Math.floor(lenHi); - M[N-1][15] = lenLo; - - // HASH COMPUTATION [§6.2.2] - - for (let i=0; i>> 0; - } - - // 2 - initialise working variables a, b, c, d, e, f, g, h with previous hash value - let a = H[0], b = H[1], c = H[2], d = H[3], e = H[4], f = H[5], g = H[6], h = H[7]; - - // 3 - main loop (note '>>> 0' for 'addition modulo 2^32') - for (let t=0; t<64; t++) { - const T1 = h + Sha256.Σ1(e) + Sha256.Ch(e, f, g) + K[t] + W[t]; - const T2 = Sha256.Σ0(a) + Sha256.Maj(a, b, c); - h = g; - g = f; - f = e; - e = (d + T1) >>> 0; - d = c; - c = b; - b = a; - a = (T1 + T2) >>> 0; - } - - // 4 - compute the new intermediate hash value (note '>>> 0' for 'addition modulo 2^32') - H[0] = (H[0]+a) >>> 0; - H[1] = (H[1]+b) >>> 0; - H[2] = (H[2]+c) >>> 0; - H[3] = (H[3]+d) >>> 0; - H[4] = (H[4]+e) >>> 0; - H[5] = (H[5]+f) >>> 0; - H[6] = (H[6]+g) >>> 0; - H[7] = (H[7]+h) >>> 0; - } - - // convert H0..H7 to hex strings (with leading zeros) - for (let h=0; h prev + String.fromCharCode(curr), ''); - } catch (e) { // no TextEncoder available? - return unescape(encodeURIComponent(str)); // monsur.hossa.in/2012/07/20/utf-8-in-javascript.html - } - } - - function hexBytesToString(hexStr) { // convert string of hex numbers to a string of chars (eg '616263' -> 'abc'). - const str = hexStr.replace(' ', ''); // allow space-separated groups - return str=='' ? '' : str.match(/.{2}/g).map(byte => String.fromCharCode(parseInt(byte, 16))).join(''); - } - } - - - - /** - * Rotates right (circular right shift) value x by n positions [§3.2.4]. - * @private - */ - static ROTR(n, x) { - return (x >>> n) | (x << (32-n)); - } - - - /** - * Logical functions [§4.1.2]. - * @private - */ - static Σ0(x) { return Sha256.ROTR(2, x) ^ Sha256.ROTR(13, x) ^ Sha256.ROTR(22, x); } - static Σ1(x) { return Sha256.ROTR(6, x) ^ Sha256.ROTR(11, x) ^ Sha256.ROTR(25, x); } - static σ0(x) { return Sha256.ROTR(7, x) ^ Sha256.ROTR(18, x) ^ (x>>>3); } - static σ1(x) { return Sha256.ROTR(17, x) ^ Sha256.ROTR(19, x) ^ (x>>>10); } - static Ch(x, y, z) { return (x & y) ^ (~x & z); } // 'choice' - static Maj(x, y, z) { return (x & y) ^ (x & z) ^ (y & z); } // 'majority' - -} - - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -if (typeof module != 'undefined' && module.exports) module.exports = Sha256; // ≡ export default Sha256 - diff --git a/test/sha256.js b/test/sha256.js deleted file mode 100644 index a00f54b..0000000 --- a/test/sha256.js +++ /dev/null @@ -1,42 +0,0 @@ -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; - -const sha256 = require("./helpers/sha256"); - -// const printSignal = require("./helpers/printsignal"); - - -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); - - console.log("Vars: "+circuit.nVars); - console.log("Constraints: "+circuit.nConstraints); - - const witness = circuit.calculateWitness({ "a": "1", "b": "2" }); - - const b = new Buffer.alloc(54); - b[26] = 1; - b[53] = 2; - - const hash = crypto.createHash("sha256") - .update(b) - .digest("hex"); - const r = "0x" + hash.slice(10); - - const hash2 = sha256.hash(b.toString("hex"), {msgFormat: "hex-bytes"}); - - assert.equal(hash, hash2); - - assert(witness[1].equals(snarkjs.bigInt(r))); - }).timeout(1000000); - - -}); diff --git a/test/sum.js b/test/sum.js deleted file mode 100644 index 009f72e..0000000 --- a/test/sum.js +++ /dev/null @@ -1,35 +0,0 @@ -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"))); - }); -});