diff --git a/circuits/circuits/dsc/openpassport_dsc.circom b/circuits/circuits/dsc/openpassport_dsc.circom index 8ec01f95..69bb011f 100644 --- a/circuits/circuits/dsc/openpassport_dsc.circom +++ b/circuits/circuits/dsc/openpassport_dsc.circom @@ -1,14 +1,14 @@ pragma circom 2.1.9; -include "../utils/circomlib/bitify/bitify.circom"; +include "circomlib/circuits/bitify.circom"; include "../utils/circomlib/hasher/shaBytes/shaBytesDynamic.circom"; -include "../utils/circomlib/bitify/comparators.circom"; +include "circomlib/circuits/comparators.circom"; include "../utils/circomlib/hasher/hash.circom"; include "../utils/circomlib/merkle-trees/binary-merkle-root.circom"; include "../utils/passport/customHashers.circom"; include "../utils/passport/signatureAlgorithm.circom"; include "../utils/passport/signatureVerifier.circom"; -include "../utils/circomlib/utils/bytes.circom"; +include "@zk-email/circuits/utils/bytes.circom"; template OPENPASSPORT_DSC(signatureAlgorithm, n_dsc, k_dsc, n_csca, k_csca, max_cert_bytes, dscPubkeyBytesLength, nLevels) { diff --git a/circuits/circuits/prove/openpassport_prove.circom b/circuits/circuits/prove/openpassport_prove.circom index c272940a..0b1d08cc 100644 --- a/circuits/circuits/prove/openpassport_prove.circom +++ b/circuits/circuits/prove/openpassport_prove.circom @@ -9,6 +9,7 @@ include "../utils/passport/passportVerifier.circom"; include "../utils/passport/disclose/disclose.circom"; include "../utils/passport/disclose/proveCountryIsNotInList.circom"; include "../utils/passport/ofac/ofac_name.circom"; +//include "@zk-email/circuits/utils/bytes.circom"; template OPENPASSPORT_PROVE(signatureAlgorithm, n, k, MAX_ECONTENT_PADDED_LEN, MAX_SIGNED_ATTR_PADDED_LEN, FORBIDDEN_COUNTRIES_LIST_LENGTH) { var kLengthFactor = getKLengthFactor(signatureAlgorithm); diff --git a/circuits/circuits/utils/circomlib/bigInt/bigInt.circom b/circuits/circuits/utils/circomlib/bigInt/bigInt.circom index f52da7fc..4736fcdd 100644 --- a/circuits/circuits/utils/circomlib/bigInt/bigInt.circom +++ b/circuits/circuits/utils/circomlib/bigInt/bigInt.circom @@ -1,7 +1,7 @@ pragma circom 2.1.6; -include "../bitify/comparators.circom"; -include "../bitify/bitify.circom"; +include "circomlib/circuits/comparators.circom"; +include "circomlib/circuits/bitify.circom"; include "./bigIntFunc.circom"; include "./bigIntOverflow.circom"; include "../int/arithmetic.circom"; diff --git a/circuits/circuits/utils/circomlib/bigInt/bigIntOverflow.circom b/circuits/circuits/utils/circomlib/bigInt/bigIntOverflow.circom index 5f453b08..deadf453 100644 --- a/circuits/circuits/utils/circomlib/bigInt/bigIntOverflow.circom +++ b/circuits/circuits/utils/circomlib/bigInt/bigIntOverflow.circom @@ -1,7 +1,7 @@ pragma circom 2.1.6; -include "../bitify/comparators.circom"; -include "../bitify/bitify.circom"; +include "circomlib/circuits/comparators.circom"; +include "circomlib/circuits/bitify.circom"; include "./bigInt.circom"; include "./bigIntFunc.circom"; include "../int/arithmetic.circom"; diff --git a/circuits/circuits/utils/circomlib/bitify/bitify.circom b/circuits/circuits/utils/circomlib/bitify/bitify.circom deleted file mode 100644 index fb347caf..00000000 --- a/circuits/circuits/utils/circomlib/bitify/bitify.circom +++ /dev/null @@ -1,50 +0,0 @@ -pragma circom 2.1.6; - -/* - 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 Num2Bits(n) { - signal input in; - signal output out[n]; - var lc1=0; - - var e2=1; - for (var i = 0; i> i) & 1; - out[i] * (out[i] -1 ) === 0; - lc1 += out[i] * e2; - e2 = e2+e2; - } - - lc1 === in; -} - -template Bits2Num(n) { - signal input in[n]; - signal output out; - var lc1=0; - - var e2 = 1; - for (var i = 0; i out; -} \ No newline at end of file diff --git a/circuits/circuits/utils/circomlib/bitify/comparators.circom b/circuits/circuits/utils/circomlib/bitify/comparators.circom deleted file mode 100644 index 430f1183..00000000 --- a/circuits/circuits/utils/circomlib/bitify/comparators.circom +++ /dev/null @@ -1,142 +0,0 @@ -pragma circom 2.1.6; - - -/* - 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 "bitify.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; -} - -template ForceEqualIfEnabled() { - signal input enabled; - signal input in[2]; - - component isz = IsZero(); - - in[1] - in[0] ==> isz.in; - - (1 - isz.out)*enabled === 0; -} - -/* -// 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; -} -*/ - -template LessThan(n) { - assert(n <= 252); - signal input in[2]; - signal output out; - - component n2b = Num2Bits(n+1); - - n2b.in <== in[0]+ (1< out; -} - -// N is the number of bits the input have. -// The MSF is the sign bit. -template GreaterThan(n) { - signal input in[2]; - signal output out; - - component lt = LessThan(n); - - lt.in[0] <== in[1]; - lt.in[1] <== in[0]; - lt.out ==> out; -} - -// N is the number of bits the input have. -// The MSF is the sign bit. -template GreaterEqThan(n) { - signal input in[2]; - signal output out; - - component lt = LessThan(n); - - lt.in[0] <== in[1]; - lt.in[1] <== in[0]+1; - lt.out ==> out; -} - diff --git a/circuits/circuits/utils/circomlib/bitify/gates.circom b/circuits/circuits/utils/circomlib/bitify/gates.circom index 73f712ce..1e260238 100644 --- a/circuits/circuits/utils/circomlib/bitify/gates.circom +++ b/circuits/circuits/utils/circomlib/bitify/gates.circom @@ -1,101 +1,6 @@ -/* - 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 . -*/ pragma circom 2.0.0; -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; -} - -template MultiAND(n) { - signal input in[n]; - signal output out; - component and1; - component and2; - component ands[2]; - if (n==1) { - out <== in[0]; - } else if (n==2) { - and1 = AND(); - and1.a <== in[0]; - and1.b <== in[1]; - out <== and1.out; - } else { - and2 = AND(); - var n1 = n\2; - var n2 = n-n\2; - ands[0] = MultiAND(n1); - ands[1] = MultiAND(n2); - var i; - for (i=0; i. -*/ - -/* - -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. - */ - pragma circom 2.0.0; - -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] * e2; - - e2 = e2+e2; - } - - // Ensure the sum; - - lin === lout; -} diff --git a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/ch.circom b/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/ch.circom deleted file mode 100644 index e95f6acc..00000000 --- a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/ch.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 . -*/ - -/* 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 - -*/ -pragma circom 2.0.0; - -template Ch_t(n) { - signal input a[n]; - signal input b[n]; - signal input c[n]; - signal output out[n]; - - for (var k=0; k. -*/ -pragma circom 2.0.0; - -template H_sha256(x) { - signal output out[32]; - var c[8] = [0x6a09e667, - 0xbb67ae85, - 0x3c6ef372, - 0xa54ff53a, - 0x510e527f, - 0x9b05688c, - 0x1f83d9ab, - 0x5be0cd19]; - - for (var i=0; i<32; i++) { - out[i] <== (c[x] >> i) & 1; - } -} - -template K_sha256(x) { - signal output out[32]; - var c[64] = [ - 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/circuits/utils/circomlib/hasher/sha2/sha256_temp/maj.circom b/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/maj.circom deleted file mode 100644 index 1c0940c2..00000000 --- a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/maj.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 . -*/ - -/* 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 - -*/ -pragma circom 2.0.0; - -template Maj_t(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. -*/ -pragma circom 2.0.0; - -template RotR(n, r) { - signal input in[n]; - signal output out[n]; - - for (var i=0; i. -*/ -pragma circom 2.0.0; - -include "constants.circom"; -include "t1.circom"; -include "t2.circom"; -include "./binsum.circom"; -include "sigmaplus.circom"; -include "sha256compression_function.circom"; - - -template Sha256compression() { - signal input hin[256]; - 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 outCalc[256] = sha256compression(hin, inp); - - var i; - for (i=0; i<256; i++) out[i] <-- outCalc[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_sha256(i); - - 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_circomlib(32, 2); - - component sume[64]; - for (i=0; i<64; i++) sume[i] = BinSum_circomlib(32, 2); - - component fsum[8]; - for (i=0; i<8; i++) fsum[i] = BinSum_circomlib(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]; - } - - for (k=0; k<32; k++) { - w[t][k] <== sigmaPlus[t-16].out[k]; - } - } - } - - for (k=0; k<32; k++ ) { - a[0][k] <== hin[k]; - b[0][k] <== hin[32*1 + k]; - c[0][k] <== hin[32*2 + k]; - d[0][k] <== hin[32*3 + k]; - e[0][k] <== hin[32*4 + k]; - f[0][k] <== hin[32*5 + k]; - g[0][k] <== hin[32*6 + k]; - h[0][k] <== hin[32*7 + 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] <== hin[32*0+k]; - fsum[0].in[1][k] <== a[64][k]; - fsum[1].in[0][k] <== hin[32*1+k]; - fsum[1].in[1][k] <== b[64][k]; - fsum[2].in[0][k] <== hin[32*2+k]; - fsum[2].in[1][k] <== c[64][k]; - fsum[3].in[0][k] <== hin[32*3+k]; - fsum[3].in[1][k] <== d[64][k]; - fsum[4].in[0][k] <== hin[32*4+k]; - fsum[4].in[1][k] <== e[64][k]; - fsum[5].in[0][k] <== hin[32*5+k]; - fsum[5].in[1][k] <== f[64][k]; - fsum[6].in[0][k] <== hin[32*6+k]; - fsum[6].in[1][k] <== g[64][k]; - fsum[7].in[0][k] <== hin[32*7+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/circuits/utils/circomlib/hasher/sha2/sha256_temp/sha256compression_function.circom b/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/sha256compression_function.circom deleted file mode 100644 index 9f8d5b86..00000000 --- a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/sha256compression_function.circom +++ /dev/null @@ -1,112 +0,0 @@ -// signal input hin[256]; -// signal input inp[512]; -// signal output out[256]; -pragma circom 2.0.0; - -function rrot(x, n) { - return ((x >> n) | (x << (32-n))) & 0xFFFFFFFF; -} - -function bsigma0(x) { - return rrot(x,2) ^ rrot(x,13) ^ rrot(x,22); -} - -function bsigma1(x) { - return rrot(x,6) ^ rrot(x,11) ^ rrot(x,25); -} - -function ssigma0(x) { - return rrot(x,7) ^ rrot(x,18) ^ (x >> 3); -} - -function ssigma1(x) { - return rrot(x,17) ^ rrot(x,19) ^ (x >> 10); -} - -function Maj(x, y, z) { - return (x&y) ^ (x&z) ^ (y&z); -} - -function Ch(x, y, z) { - return (x & y) ^ ((0xFFFFFFFF ^x) & z); -} - -function sha256K(i) { - var k[64] = [ - 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 - ]; - return k[i]; -} - -function sha256compression(hin, inp) { - var H[8]; - var a; - var b; - var c; - var d; - var e; - var f; - var g; - var h; - var out[256]; - for (var i=0; i<8; i++) { - H[i] = 0; - for (var j=0; j<32; j++) { - H[i] += hin[i*32+j] << j; - } - } - a=H[0]; - b=H[1]; - c=H[2]; - d=H[3]; - e=H[4]; - f=H[5]; - g=H[6]; - h=H[7]; - var w[64]; - var T1; - var T2; - for (var i=0; i<64; i++) { - if (i<16) { - w[i]=0; - for (var j=0; j<32; j++) { - w[i] += inp[i*32+31-j]<> j) & 1; - } - } - return out; -} diff --git a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/shift.circom b/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/shift.circom deleted file mode 100644 index 317cd328..00000000 --- a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/shift.circom +++ /dev/null @@ -1,33 +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 . -*/ -pragma circom 2.0.0; - -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/circuits/utils/circomlib/hasher/sha2/sha256_temp/sigma.circom b/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/sigma.circom deleted file mode 100644 index bcb0b805..00000000 --- a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/sigma.circom +++ /dev/null @@ -1,77 +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 . -*/ -pragma circom 2.0.0; - -include "xor3.circom"; -include "rotate.circom"; -include "shift.circom"; - -template SmallSigma(ra, rb, rc) { - signal input in[32]; - signal output out[32]; - var k; - - component rota = RotR(32, ra); - component rotb = RotR(32, rb); - component shrc = ShR(32, rc); - - for (k=0; k<32; k++) { - rota.in[k] <== in[k]; - rotb.in[k] <== in[k]; - shrc.in[k] <== in[k]; - } - - component xor3 = Xor3(32); - for (k=0; k<32; k++) { - xor3.a[k] <== rota.out[k]; - xor3.b[k] <== rotb.out[k]; - xor3.c[k] <== shrc.out[k]; - } - - for (k=0; k<32; k++) { - out[k] <== xor3.out[k]; - } -} - -template BigSigma(ra, rb, rc) { - signal input in[32]; - signal output out[32]; - var k; - - component rota = RotR(32, ra); - component rotb = RotR(32, rb); - component rotc = RotR(32, rc); - for (k=0; k<32; k++) { - rota.in[k] <== in[k]; - rotb.in[k] <== in[k]; - rotc.in[k] <== in[k]; - } - - component xor3 = Xor3(32); - - for (k=0; k<32; k++) { - xor3.a[k] <== rota.out[k]; - xor3.b[k] <== rotb.out[k]; - xor3.c[k] <== rotc.out[k]; - } - - for (k=0; k<32; k++) { - out[k] <== xor3.out[k]; - } -} diff --git a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/sigmaplus.circom b/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/sigmaplus.circom deleted file mode 100644 index 5782613c..00000000 --- a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/sigmaplus.circom +++ /dev/null @@ -1,50 +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 . -*/ -pragma circom 2.0.0; - -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]; - var k; - - component sigma1 = SmallSigma(17,19,10); - component sigma0 = SmallSigma(7, 18, 3); - for (k=0; k<32; k++) { - sigma1.in[k] <== in2[k]; - sigma0.in[k] <== in15[k]; - } - - component sum = BinSum_circomlib(32, 4); - for (k=0; k<32; 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]; - } - - for (k=0; k<32; k++) { - out[k] <== sum.out[k]; - } -} diff --git a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/t1.circom b/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/t1.circom deleted file mode 100644 index cb4a679f..00000000 --- a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/t1.circom +++ /dev/null @@ -1,58 +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 . -*/ -pragma circom 2.0.0; - -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]; - - var ki; - - component ch = Ch_t(32); - component bigsigma1 = BigSigma(6, 11, 25); - - for (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]; - } - - component sum = BinSum_circomlib(32, 5); - for (ki=0; ki<32; 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]; - } - - for (ki=0; ki<32; ki++) { - out[ki] <== sum.out[ki]; - } -} diff --git a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/t2.circom b/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/t2.circom deleted file mode 100644 index 90f5512a..00000000 --- a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/t2.circom +++ /dev/null @@ -1,51 +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 . -*/ -pragma circom 2.0.0; - -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]; - var k; - - component bigsigma0 = BigSigma(2, 13, 22); - component maj = Maj_t(32); - for (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]; - } - - component sum = BinSum_circomlib(32, 2); - - for (k=0; k<32; k++) { - sum.in[0][k] <== bigsigma0.out[k]; - sum.in[1][k] <== maj.out[k]; - } - - for (k=0; k<32; k++) { - out[k] <== sum.out[k]; - } -} diff --git a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/xor3.circom b/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/xor3.circom deleted file mode 100644 index 9c21e4e2..00000000 --- a/circuits/circuits/utils/circomlib/hasher/sha2/sha256_temp/xor3.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 . -*/ - -/* 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 - -*/ -pragma circom 2.0.0; - -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> 9); - paddedInLength === inBlockIndex * 512; - - // These verify the unconstrained floor calculation is the uniquely correct integer that represents the floor - // component floorVerifierUnder = LessEqThan(maxBitsPaddedBits); // todo verify the length passed in is less than nbits. note that maxBitsPaddedBits can likely be lowered or made it a fn of maxbits - // floorVerifierUnder.in[0] <== (inBlockIndex)*512; - // floorVerifierUnder.in[1] <== paddedInLength; - // floorVerifierUnder.out === 1; - - // component floorVerifierOver = GreaterThan(maxBitsPaddedBits); - // floorVerifierOver.in[0] <== (inBlockIndex+1)*512; - // floorVerifierOver.in[1] <== paddedInLength; - // floorVerifierOver.out === 1; - - // These verify we pass in a valid number of bits to the SHA256 compression circuit. - component bitLengthVerifier = LessEqThan(maxBitsPaddedBits); // todo verify the length passed in is less than nbits. note that maxBitsPaddedBits can likely be lowered or made it a fn of maxbits - bitLengthVerifier.in[0] <== paddedInLength; - bitLengthVerifier.in[1] <== maxBitLength; - bitLengthVerifier.out === 1; - - // Note that we can no longer do padded verification efficiently inside the SHA because it requires non deterministic array indexing. - // We can do it if we add a constraint, but since guessing a valid SHA2 preimage is hard anyways, we'll just do it outside the circuit. - - // signal paddedIn[maxBlocks*512]; - // for (k=0; k> k)&1; - // } - - component ha0 = H_sha256(0); - component hb0 = H_sha256(1); - component hc0 = H_sha256(2); - component hd0 = H_sha256(3); - component he0 = H_sha256(4); - component hf0 = H_sha256(5); - component hg0 = H_sha256(6); - component hh0 = H_sha256(7); - - component sha256compression[maxBlocks]; - - for (i=0; i= end); - assert(start >= 0); - assert(end >= start); - - signal input in[n]; - signal output out[end - start]; - - for (var i = start; i < end; i++) { - out[i - start] <== in[i]; - } -} - -/// @title CheckSubstringMatch -/// @notice Check if a substring matches the input array -/// @param maxSubstringLen The maximum length of the substring -/// @input input The portion of the input array to check -/// @input substring The substring pattern to match -/// @output isMatch 1 if the substring matches, 0 otherwise -template CheckSubstringMatch(maxSubstringLen) { - signal input in[maxSubstringLen]; - signal input substring[maxSubstringLen]; - signal output isMatch; - - // Ensure the first element of the pattern is non-zero - signal firstElementNonZero; - firstElementNonZero <== IsZero()(substring[0]); - firstElementNonZero === 0; - - signal matchAccumulator[maxSubstringLen + 1]; - signal difference[maxSubstringLen]; - signal isZeroDifference[maxSubstringLen]; - - matchAccumulator[0] <== 1; - - for (var i = 0; i < maxSubstringLen; i++) { - difference[i] <== (in[i] - substring[i]) * substring[i]; - isZeroDifference[i] <== IsZero()(difference[i]); - matchAccumulator[i + 1] <== matchAccumulator[i] * isZeroDifference[i]; - } - - isMatch <== matchAccumulator[maxSubstringLen]; -} - -/// @title CountSubstringOccurrences -/// @notice Count the number of times a substring occurs in the input array -/// @param maxLen The maximum length of the input array -/// @param maxSubstringLen The maximum length of the substring -/// @input in The input array to search in -/// @input substring The substring to search for -/// @output count The number of occurrences of the substring in the input -template CountSubstringOccurrences(maxLen, maxSubstringLen) { - assert(maxLen >= maxSubstringLen); - - signal input in[maxLen]; - signal input substring[maxSubstringLen]; - signal output count; - - // Check for matches at each possible starting position - component matches[maxLen]; - for (var i = 0; i < maxLen; i++) { - matches[i] = CheckSubstringMatch(maxSubstringLen); - for (var j = 0; j < maxSubstringLen; j++) { - if (i + j < maxLen) { - matches[i].in[j] <== in[i + j]; - } else { - matches[i].in[j] <== 0; - } - } - matches[i].substring <== substring; - } - - // Sum up all matches to get the total count - component summer = CalculateTotal(maxLen); - for (var i = 0; i < maxLen; i++) { - summer.nums[i] <== matches[i].isMatch; - } - - count <== summer.sum; -} \ No newline at end of file diff --git a/circuits/circuits/utils/circomlib/utils/bytes.circom b/circuits/circuits/utils/circomlib/utils/bytes.circom deleted file mode 100644 index e5e4948e..00000000 --- a/circuits/circuits/utils/circomlib/utils/bytes.circom +++ /dev/null @@ -1,225 +0,0 @@ -pragma circom 2.1.6; - -include "../bitify/bitify.circom"; -include "../bitify/comparators.circom"; -include "./array.circom"; -include "./constants.circom"; -include "./functions.circom"; - - -function computeIntChunkLength(byteLength) { - var packSize = MAX_BYTES_IN_FIELD(); - - var remain = byteLength % packSize; - var numChunks = (byteLength - remain) / packSize; - if (remain > 0) { - numChunks += 1; - } - - return numChunks; -} - - -/// @title PackBytes -/// @notice Pack an array of bytes to numbers that fit in the field -/// @param maxBytes the maximum number of bytes in the input array -/// @input in the input byte array; assumes elements to be bytes -/// @output out the output integer array -template PackBytes(maxBytes) { - var packSize = MAX_BYTES_IN_FIELD(); - var maxInts = computeIntChunkLength(maxBytes); - - signal input in[maxBytes]; - signal output out[maxInts]; - - signal intSums[maxInts][packSize]; - - for (var i = 0; i < maxInts; i++) { - for(var j=0; j < packSize; j++) { - var idx = packSize * i + j; - - // Copy the previous value if we are out of bounds - we take last item as final result - if(idx >= maxBytes) { - intSums[i][j] <== intSums[i][j-1]; - } - // First item of each chunk is the byte itself - else if (j == 0){ - intSums[i][j] <== in[idx]; - } - // Every other item is 256^j * byte - else { - intSums[i][j] <== intSums[i][j-1] + (1 << (8*j)) * in[idx]; - } - } - } - - // Last item of each chunk is the final sum - for (var i = 0; i < maxInts; i++) { - out[i] <== intSums[i][packSize-1]; - } -} - - -/// @title PackByteSubArray -/// @notice Select sub array from the input array and pack it to numbers that fit in the field -/// @notice This is not used in ZK-Email circuits anywhere -/// @param maxArrayLen the maximum number of elements in the input array -/// @param maxSubArrayLen the maximum number of elements in the sub array -/// @input in the input byte array; assumes elements to be bytes -/// @input startIndex the start index of the sub array; assumes to be a valid index -/// @input length the length of the sub array; assumes to fit in `ceil(log2(maxSubArrayLen))` bits -/// @output out the output integer array -template PackByteSubArray(maxArrayLen, maxSubArrayLen) { - assert(maxSubArrayLen < maxArrayLen); - var chunkLength = computeIntChunkLength(maxSubArrayLen); - - signal input in[maxArrayLen]; - signal input startIndex; - signal input length; - - signal output out[chunkLength]; - - component SelectSubArray = SelectSubArray(maxArrayLen, maxSubArrayLen); - SelectSubArray.in <== in; - SelectSubArray.startIndex <== startIndex; - SelectSubArray.length <== length; - - component packer = PackBytes(maxSubArrayLen); - packer.in <== SelectSubArray.out; - - out <== packer.out; -} - - -/// @title DigitBytesToInt -/// @notice Converts a byte array representing digits to an integer -/// @notice Assumes the output number fits in the field -/// @param n The number of bytes in the input array -/// @input in The input byte array; assumes elements are between 48 and 57 (ASCII numbers) -/// @output out The output integer; assumes to fit in the field -template DigitBytesToInt(n) { - signal input in[n]; - - signal output out; - - signal sums[n+1]; - sums[0] <== 0; - - for(var i = 0; i < n; i++) { - sums[i + 1] <== 10 * sums[i] + (in[i] - 48); - } - - out <== sums[n]; -} - - -// NOTE: this circuit is unaudited and should not be used in production -/// @title SplitBytesToWords -/// @notice split an array of bytes into an array of words -/// @notice useful for casting a message or modulus before RSA verification -/// @param l: number of bytes in the input array -/// @param n: number of bits in a word -/// @param k: number of words -/// @input in: array of bytes -/// @output out: array of words -template SplitBytesToWords (l,n,k) { - signal input in[l]; - signal output out[k]; - - component num2bits[l]; - for (var i = 0 ; i < l ; i++){ - num2bits[i] = Num2Bits(8); - num2bits[i].in <== in[i]; - } - component bits2num[k]; - for (var i = 0 ; i < k ; i++){ - bits2num[i] = Bits2Num(n); - for(var j = 0 ; j < n ; j++){ - if(i*n + j >= 8 * l){ - bits2num[i].in[j] <== 0; - } - else{ - bits2num[i].in[j] <== num2bits[l - (( i * n + j) \ 8) - 1].out[ ((i * n + j) % 8)]; - } - } - } - for( var i = 0 ; i< k ; i++){ - out[i] <== bits2num[i].out; - } -} - -// Asserts that a given input is binary. -// -// Inputs: -// - in: an input signal, expected to be 0 or 1. -template AssertBit() { - signal input in; - in * (in - 1) === 0; -} - -// The ByteMask template masks an input array using a binary mask array. -// Each element in the input array is multiplied by the corresponding element in the mask array. -// The mask array is validated to ensure all elements are binary (0 or 1). -// -// Parameters: -// - maxLength: The maximum length of the input and mask arrays. -// -// Inputs: -// - body: An array of signals representing the body to be masked. -// - mask: An array of signals representing the binary mask. -// -// Outputs: -// - out: An array of signals representing the masked input. -template ByteMask(maxLength) { - signal input in[maxLength]; - signal input mask[maxLength]; - signal output out[maxLength]; - - component bit_check[maxLength]; - - for (var i = 0; i < maxLength; i++) { - bit_check[i] = AssertBit(); - bit_check[i].in <== mask[i]; - out[i] <== in[i] * mask[i]; - } -} - -/// NOTE: this circuit is unaudited and should not be used in production -/// @title SplitBytesToWords -/// @notice split an array of bytes into an array of words -/// @notice useful for casting a message or modulus before RSA verification -/// @param l: number of bytes in the input array -/// @param n: number of bits in a word -/// @param k: number of words -/// @input in: array of bytes -/// @output out: array of words -template SplitSignalsToWords (t,l,n,k) { - assert(n*k >= t*l); - - signal input in[l]; - signal output out[k]; - component num2bits[l]; - for (var i = 0 ; i < l ; i++){ - num2bits[i] = Num2Bits(t); - num2bits[i].in <== in[i]; - } - for (var i = 0 ; i < t ; i ++){ - } - component bits2num[k]; - for (var i = 0 ; i < k ; i++){ - bits2num[i] = Bits2Num(n); - - for(var j = 0 ; j < n ; j++){ - if(i*n + j >= l * t){ - bits2num[i].in[j] <== 0; - } - else{ - bits2num[i].in[j] <== num2bits[ (( i * n + j) \ t) ].out[ ((i * n + j) % t)]; - } - } - } - for( var i = 0 ; i< k ; i++){ - out[i] <== bits2num[i].out; - } - -} \ No newline at end of file diff --git a/circuits/circuits/utils/circomlib/utils/compconstant.circom b/circuits/circuits/utils/circomlib/utils/compconstant.circom index 075442f5..f3156c04 100644 --- a/circuits/circuits/utils/circomlib/utils/compconstant.circom +++ b/circuits/circuits/utils/circomlib/utils/compconstant.circom @@ -18,7 +18,7 @@ */ pragma circom 2.0.0; -include "../bitify/bitify.circom"; +include "circomlib/circuits/bitify.circom"; // Returns 1 if in (in binary) > ct diff --git a/circuits/circuits/utils/circomlib/utils/constants.circom b/circuits/circuits/utils/circomlib/utils/constants.circom deleted file mode 100644 index 69edec43..00000000 --- a/circuits/circuits/utils/circomlib/utils/constants.circom +++ /dev/null @@ -1,15 +0,0 @@ -pragma circom 2.1.6; - - -function EMAIL_ADDR_MAX_BYTES() { - return 256; -} - -function DOMAIN_MAX_BYTES() { - return 255; -} - -// Field support maximum of ~253 bit -function MAX_BYTES_IN_FIELD() { - return 31; -} \ No newline at end of file diff --git a/circuits/circuits/utils/circomlib/utils/functions.circom b/circuits/circuits/utils/circomlib/utils/functions.circom deleted file mode 100644 index b0a695dc..00000000 --- a/circuits/circuits/utils/circomlib/utils/functions.circom +++ /dev/null @@ -1,17 +0,0 @@ -pragma circom 2.1.6; - -/// @function log2Ceil -/// @notice Calculate log2 of a number and round it up -/// @param a The input value -/// @return The result of the log2Ceil -function log2Ceil(a) { - var n = a - 1; - var r = 0; - - while (n > 0) { - r++; - n \= 2; - } - - return r; -} \ No newline at end of file diff --git a/circuits/circuits/utils/passport/computeCommitment.circom b/circuits/circuits/utils/passport/computeCommitment.circom index 46cd8852..abfe77d1 100644 --- a/circuits/circuits/utils/passport/computeCommitment.circom +++ b/circuits/circuits/utils/passport/computeCommitment.circom @@ -1,7 +1,7 @@ pragma circom 2.1.9; include "../circomlib/hasher/hash.circom"; -include "../circomlib/utils/bytes.circom"; +include "@zk-email/circuits/utils/bytes.circom"; include "./customHashers.circom"; template ComputeCommitment() { diff --git a/circuits/circuits/utils/passport/date/dateIsLess.circom b/circuits/circuits/utils/passport/date/dateIsLess.circom index 7e1ab58d..9dc3bafa 100644 --- a/circuits/circuits/utils/passport/date/dateIsLess.circom +++ b/circuits/circuits/utils/passport/date/dateIsLess.circom @@ -1,6 +1,6 @@ pragma circom 2.1.9; -include "../../circomlib/bitify/comparators.circom"; +include "circomlib/circuits/comparators.circom"; template DateIsLess() { signal input firstDay; diff --git a/circuits/circuits/utils/passport/date/isOlderThan.circom b/circuits/circuits/utils/passport/date/isOlderThan.circom index 28558cee..ee7b4f1a 100644 --- a/circuits/circuits/utils/passport/date/isOlderThan.circom +++ b/circuits/circuits/utils/passport/date/isOlderThan.circom @@ -1,7 +1,7 @@ pragma circom 2.1.9; -include "../../circomlib/bitify/comparators.circom"; -include "../../circomlib/bitify/bitify.circom"; +include "circomlib/circuits/comparators.circom"; +include "circomlib/circuits/bitify.circom"; include "./dateIsLess.circom"; template IsOlderThan() { diff --git a/circuits/circuits/utils/passport/date/isValid.circom b/circuits/circuits/utils/passport/date/isValid.circom index 9c45654d..c6570b9b 100644 --- a/circuits/circuits/utils/passport/date/isValid.circom +++ b/circuits/circuits/utils/passport/date/isValid.circom @@ -1,7 +1,7 @@ pragma circom 2.1.9; -include "../../circomlib/bitify/comparators.circom"; -include "../../circomlib/bitify/bitify.circom"; +include "circomlib/circuits/comparators.circom"; +include "circomlib/circuits/bitify.circom"; include "./dateIsLess.circom"; template IsValid() { diff --git a/circuits/circuits/utils/passport/disclose/disclose.circom b/circuits/circuits/utils/passport/disclose/disclose.circom index d74f5151..346e5b16 100644 --- a/circuits/circuits/utils/passport/disclose/disclose.circom +++ b/circuits/circuits/utils/passport/disclose/disclose.circom @@ -1,6 +1,6 @@ pragma circom 2.1.9; -include "../../circomlib/utils/bytes.circom"; +include "@zk-email/circuits/utils/bytes.circom"; include "../date/isOlderThan.circom"; template DISCLOSE() { diff --git a/circuits/circuits/utils/passport/disclose/proveCountryIsNotInList.circom b/circuits/circuits/utils/passport/disclose/proveCountryIsNotInList.circom index a6deb16f..2bb7968b 100644 --- a/circuits/circuits/utils/passport/disclose/proveCountryIsNotInList.circom +++ b/circuits/circuits/utils/passport/disclose/proveCountryIsNotInList.circom @@ -1,7 +1,7 @@ pragma circom 2.1.5; -include "../../circomlib/bitify/comparators.circom"; -include "../../circomlib/utils/bytes.circom"; +include "circomlib/circuits/comparators.circom"; +include "@zk-email/circuits/utils/bytes.circom"; template ProveCountryIsNotInList(forbiddenCountriesListLength) { signal input dg1[93]; diff --git a/circuits/circuits/utils/passport/disclose/verify_commitment.circom b/circuits/circuits/utils/passport/disclose/verify_commitment.circom index 07240a0c..0f4de624 100644 --- a/circuits/circuits/utils/passport/disclose/verify_commitment.circom +++ b/circuits/circuits/utils/passport/disclose/verify_commitment.circom @@ -1,6 +1,6 @@ pragma circom 2.1.9; -include "../../circomlib/utils/bytes.circom"; +include "@zk-email/circuits/utils/bytes.circom"; include "../../circomlib/merkle-trees/binary-merkle-root.circom"; include "../computeCommitment.circom"; diff --git a/circuits/circuits/utils/passport/passportVerifier.circom b/circuits/circuits/utils/passport/passportVerifier.circom index 8a662b31..42cf0b0a 100644 --- a/circuits/circuits/utils/passport/passportVerifier.circom +++ b/circuits/circuits/utils/passport/passportVerifier.circom @@ -1,7 +1,7 @@ pragma circom 2.1.9; -include "../circomlib/utils/array.circom"; -include "../circomlib/utils/bytes.circom"; +include "@zk-email/circuits/utils/array.circom"; +include "@zk-email/circuits/utils/bytes.circom"; include "../circomlib/hasher/shaBytes/shaBytesDynamic.circom"; include "../circomlib/hasher/hash.circom"; include "./signatureAlgorithm.circom"; diff --git a/circuits/circuits/utils/passport/signatureVerifier.circom b/circuits/circuits/utils/passport/signatureVerifier.circom index 5c99da2b..86095d12 100644 --- a/circuits/circuits/utils/passport/signatureVerifier.circom +++ b/circuits/circuits/utils/passport/signatureVerifier.circom @@ -9,7 +9,7 @@ include "secp256r1Verifier.circom"; // include "../circomlib/signature/rsa/verifyLargeRsaPkcs1v1_5.circom"; include "../circomlib/signature/rsa/verifyRsa3Pkcs1v1_5.circom"; include "../circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom"; -include "../circomlib/utils/bytes.circom"; +include "@zk-email/circuits/utils/bytes.circom"; template SignatureVerifier(signatureAlgorithm, n, k) { var kLengthFactor = getKLengthFactor(signatureAlgorithm); diff --git a/circuits/circuits/utils/zkemail/lib/base64.circom b/circuits/circuits/utils/zkemail/lib/base64.circom deleted file mode 100644 index 77dc745c..00000000 --- a/circuits/circuits/utils/zkemail/lib/base64.circom +++ /dev/null @@ -1,128 +0,0 @@ -pragma circom 2.1.6; - -include "circomlib/circuits/comparators.circom"; - - -/// @title Base64Decode -/// @notice Decodes a Base64 encoded string to array of bytes. -/// @notice Only support inputs with length = `byteLength` (no 0 padding). -/// @notice It is known that padding char '=' can be replaed with `A` to produce the same output -/// as Base64Lookup returns `0` for both, but a pracical attack from this is unlikely. -/// @param byteLength Byte length of the encoded value - length of the output array. -/// @input in Base64 encoded string; assumes elements to be valid Base64 characters. -/// @output out Decoded array of bytes. -template Base64Decode_ZK_EMAIL(byteLength) { - var charLength = 4 * ((byteLength + 2) \ 3); // 4 chars encode 3 bytes - - signal input in[charLength]; - signal output out[byteLength]; - - component bitsIn[charLength\4][4]; - component bitsOut[charLength\4][3]; - component translate[charLength\4][4]; - - var idx = 0; - for (var i = 0; i < charLength; i += 4) { - for (var j = 0; j < 3; j++) { - bitsOut[i\4][j] = Bits2Num(8); - } - - for (var j = 0; j < 4; j++) { - bitsIn[i\4][j] = Num2Bits(6); - translate[i\4][j] = Base64Lookup(); - translate[i\4][j].in <== in[i+j]; - translate[i\4][j].out ==> bitsIn[i\4][j].in; - } - - // Do the re-packing from four 6-bit words to three 8-bit words. - for (var j = 0; j < 6; j++) { - bitsOut[i\4][0].in[j+2] <== bitsIn[i\4][0].out[j]; - } - bitsOut[i\4][0].in[0] <== bitsIn[i\4][1].out[4]; - bitsOut[i\4][0].in[1] <== bitsIn[i\4][1].out[5]; - - for (var j = 0; j < 4; j++) { - bitsOut[i\4][1].in[j+4] <== bitsIn[i\4][1].out[j]; - } - for (var j = 0; j < 4; j++) { - bitsOut[i\4][1].in[j] <== bitsIn[i\4][2].out[j+2]; - } - - bitsOut[i\4][2].in[6] <== bitsIn[i\4][2].out[0]; - bitsOut[i\4][2].in[7] <== bitsIn[i\4][2].out[1]; - for (var j = 0; j < 6; j++) { - bitsOut[i\4][2].in[j] <== bitsIn[i\4][3].out[j]; - } - - for (var j = 0; j < 3; j++) { - if (idx+j < byteLength) { - out[idx+j] <== bitsOut[i\4][j].out; - } - } - idx += 3; - } -} - - -/// @title Base64Lookup -/// @notice http://0x80.pl/notesen/2016-01-17-sse-base64-decoding.html#vector-lookup-base -/// @input in input character; assumes input to be valid Base64 character (though constrained implicitly). -/// @output out output bit value. -template Base64Lookup_ZK_EMAIL() { - signal input in; - signal output out; - - // ['A', 'Z'] - component le_Z = LessThan(8); - le_Z.in[0] <== in; - le_Z.in[1] <== 90+1; - - component ge_A = GreaterThan(8); - ge_A.in[0] <== in; - ge_A.in[1] <== 65-1; - - signal range_AZ <== ge_A.out * le_Z.out; - signal sum_AZ <== range_AZ * (in - 65); - - // ['a', 'z'] - component le_z = LessThan(8); - le_z.in[0] <== in; - le_z.in[1] <== 122+1; - - component ge_a = GreaterThan(8); - ge_a.in[0] <== in; - ge_a.in[1] <== 97-1; - - signal range_az <== ge_a.out * le_z.out; - signal sum_az <== sum_AZ + range_az * (in - 71); - - // ['0', '9'] - component le_9 = LessThan(8); - le_9.in[0] <== in; - le_9.in[1] <== 57+1; - - component ge_0 = GreaterThan(8); - ge_0.in[0] <== in; - ge_0.in[1] <== 48-1; - - signal range_09 <== ge_0.out * le_9.out; - signal sum_09 <== sum_az + range_09 * (in + 4); - - // '+' - component equal_plus = IsZero(); - equal_plus.in <== in - 43; - signal sum_plus <== sum_09 + equal_plus.out * (in + 19); - - // '/' - component equal_slash = IsZero(); - equal_slash.in <== in - 47; - signal sum_slash <== sum_plus + equal_slash.out * (in + 16); - - out <== sum_slash; - - // '=' - component equal_eqsign = IsZero(); - equal_eqsign.in <== in - 61; - - 1 === range_AZ + range_az + range_09 + equal_plus.out + equal_slash.out + equal_eqsign.out; -} diff --git a/circuits/circuits/utils/zkemail/lib/bigint-func.circom b/circuits/circuits/utils/zkemail/lib/bigint-func.circom deleted file mode 100644 index bcd0d09b..00000000 --- a/circuits/circuits/utils/zkemail/lib/bigint-func.circom +++ /dev/null @@ -1,264 +0,0 @@ -pragma circom 2.1.6; - - -function div_ceil(m, n) { - var ret = 0; - if (m % n == 0) { - ret = m \ n; - } else { - ret = m \ n + 1; - } - return ret; -} - -function log_ceil(n) { - var n_temp = n; - for (var i = 0; i < 254; i++) { - if (n_temp == 0) { - return i; - } - n_temp = n_temp \ 2; - } - return 254; -} - -// m bits per overflowed register (values are potentially negative) -// n bits per properly-sized register -// in has k registers -// out has k + ceil(m/n) - 1 + 1 registers. highest-order potentially negative, -// all others are positive -// - 1 since the last register is included in the last ceil(m/n) array -// + 1 since the carries from previous registers could push you over -function getProperRepresentation(m, n, k, in) { - var ceilMN = div_ceil(m, n); - - var out[100]; // should be out[k + ceilMN] - assert(k + ceilMN < 100); - for (var i = 0; i < k; i++) { - out[i] = in[i]; - } - for (var i = k; i < 100; i++) { - out[i] = 0; - } - assert(n <= m); - for (var i = 0; i+1 < k + ceilMN; i++) { - assert((1 << m) >= out[i] && out[i] >= -(1 << m)); - var shifted_val = out[i] + (1 << m); - assert(0 <= shifted_val && shifted_val <= (1 << (m+1))); - out[i] = shifted_val & ((1 << n) - 1); - out[i+1] += (shifted_val >> n) - (1 << (m - n)); - } - - return out; -} - -// Evaluate polynomial a at point x -function poly_eval(len, a, x) { - var v = 0; - for (var i = 0; i < len; i++) { - v += a[i] * (x ** i); - } - return v; -} - -// Interpolate a degree len-1 polynomial given its evaluations at 0..len-1 -function poly_interp(len, v) { - assert(len <= 200); - var out[200]; - for (var i = 0; i < len; i++) { - out[i] = 0; - } - - // Product_{i=0..len-1} (x-i) - var full_poly[201]; - full_poly[0] = 1; - for (var i = 0; i < len; i++) { - full_poly[i+1] = 0; - for (var j = i; j >= 0; j--) { - full_poly[j+1] += full_poly[j]; - full_poly[j] *= -i; - } - } - - for (var i = 0; i < len; i++) { - var cur_v = 1; - for (var j = 0; j < len; j++) { - if (i == j) { - // do nothing - } else { - cur_v *= i-j; - } - } - cur_v = v[i] / cur_v; - - var cur_rem = full_poly[len]; - for (var j = len-1; j >= 0; j--) { - out[j] += cur_v * cur_rem; - cur_rem = full_poly[j] + i * cur_rem; - } - assert(cur_rem == 0); - } - - return out; -} - -// 1 if true, 0 if false -function long_gt(n, k, a, b) { - for (var i = k - 1; i >= 0; i--) { - if (a[i] > b[i]) { - return 1; - } - if (a[i] < b[i]) { - return 0; - } - } - return 0; -} - -// n bits per register -// a has k registers -// b has k registers -// a >= b -function long_sub(n, k, a, b) { - var diff[100]; - var borrow[100]; - for (var i = 0; i < k; i++) { - if (i == 0) { - if (a[i] >= b[i]) { - diff[i] = a[i] - b[i]; - borrow[i] = 0; - } else { - diff[i] = a[i] - b[i] + (1 << n); - borrow[i] = 1; - } - } else { - if (a[i] >= b[i] + borrow[i - 1]) { - diff[i] = a[i] - b[i] - borrow[i - 1]; - borrow[i] = 0; - } else { - diff[i] = (1 << n) + a[i] - b[i] - borrow[i - 1]; - borrow[i] = 1; - } - } - } - return diff; -} - -// a is a n-bit scalar -// b has k registers -function long_scalar_mult(n, k, a, b) { - var out[100]; - for (var i = 0; i < 100; i++) { - out[i] = 0; - } - for (var i = 0; i < k; i++) { - var temp = out[i] + (a * b[i]); - out[i] = temp % (1 << n); - out[i + 1] = out[i + 1] + temp \ (1 << n); - } - return out; -} - - -// n bits per register -// a has k + m registers -// b has k registers -// out[0] has length m + 1 -- quotient -// out[1] has length k -- remainder -// implements algorithm of https://people.eecs.berkeley.edu/~fateman/282/F%20Wright%20notes/week4.pdf -function long_div(n, k, m, a, b){ - var out[2][100]; - m += k; - while (b[k-1] == 0) { - out[1][k] = 0; - k--; - assert(k > 0); - } - m -= k; - - var remainder[100]; - for (var i = 0; i < m + k; i++) { - remainder[i] = a[i]; - } - - var mult[200]; - var dividend[200]; - for (var i = m; i >= 0; i--) { - if (i == m) { - dividend[k] = 0; - for (var j = k - 1; j >= 0; j--) { - dividend[j] = remainder[j + m]; - } - } else { - for (var j = k; j >= 0; j--) { - dividend[j] = remainder[j + i]; - } - } - - out[0][i] = short_div(n, k, dividend, b); - - var mult_shift[100] = long_scalar_mult(n, k, out[0][i], b); - var subtrahend[200]; - for (var j = 0; j < m + k; j++) { - subtrahend[j] = 0; - } - for (var j = 0; j <= k; j++) { - if (i + j < m + k) { - subtrahend[i + j] = mult_shift[j]; - } - } - remainder = long_sub(n, m + k, remainder, subtrahend); - } - for (var i = 0; i < k; i++) { - out[1][i] = remainder[i]; - } - out[1][k] = 0; - - return out; -} - -// n bits per register -// a has k + 1 registers -// b has k registers -// assumes leading digit of b is at least 2 ** (n - 1) -// 0 <= a < (2**n) * b -function short_div_norm(n, k, a, b) { - var qhat = (a[k] * (1 << n) + a[k - 1]) \ b[k - 1]; - if (qhat > (1 << n) - 1) { - qhat = (1 << n) - 1; - } - - var mult[100] = long_scalar_mult(n, k, qhat, b); - if (long_gt(n, k + 1, mult, a) == 1) { - mult = long_sub(n, k + 1, mult, b); - if (long_gt(n, k + 1, mult, a) == 1) { - return qhat - 2; - } else { - return qhat - 1; - } - } else { - return qhat; - } -} - -// n bits per register -// a has k + 1 registers -// b has k registers -// assumes leading digit of b is non-zero -// 0 <= a < (2**n) * b -function short_div(n, k, a, b) { - var scale = (1 << n) \ (1 + b[k - 1]); - - // k + 2 registers now - var norm_a[100] = long_scalar_mult(n, k + 1, scale, a); - // k + 1 registers now - var norm_b[100] = long_scalar_mult(n, k, scale, b); - - var ret; - if (norm_b[k] != 0) { - ret = short_div_norm(n, k + 1, norm_a, norm_b); - } else { - ret = short_div_norm(n, k, norm_a, norm_b); - } - return ret; -} diff --git a/circuits/circuits/utils/zkemail/lib/bigint.circom b/circuits/circuits/utils/zkemail/lib/bigint.circom deleted file mode 100644 index 3ad7bfd6..00000000 --- a/circuits/circuits/utils/zkemail/lib/bigint.circom +++ /dev/null @@ -1,94 +0,0 @@ -pragma circom 2.1.6; - -include "../../circomlib/bitify/comparators.circom"; -include "../../circomlib/bitify/bitify.circom"; -include "../../circomlib/bitify/gates.circom"; -include "./bigint-func.circom"; - - -/// @template BigLessThan -/// @notice Less than comparison for big integers -/// @param n The number of bits in each chunk -/// @param k The number of chunks -/// @param a The first bigint; assumes to consist of `k` chunks, each of which must fit in `n` bits -/// @param b The second bigint; assumes to consist of `k` chunks, each of which must fit in `n` bits -/// @param out The output of the comparison -template BigLessThan(n, k){ - signal input a[k]; - signal input b[k]; - signal output out; - - component lt[k]; - component eq[k]; - for (var i = 0; i < k; i++) { - lt[i] = LessThan(n); - lt[i].in[0] <== a[i]; - lt[i].in[1] <== b[i]; - eq[i] = IsEqual(); - eq[i].in[0] <== a[i]; - eq[i].in[1] <== b[i]; - } - - // ors[i] holds (lt[k - 1] || (eq[k - 1] && lt[k - 2]) .. || (eq[k - 1] && .. && lt[i])) - // ands[i] holds (eq[k - 1] && .. && lt[i]) - // eq_ands[i] holds (eq[k - 1] && .. && eq[i]) - component ors[k - 1]; - component ands[k - 1]; - component eq_ands[k - 1]; - for (var i = k - 2; i >= 0; i--) { - ands[i] = AND(); - eq_ands[i] = AND(); - ors[i] = OR(); - - if (i == k - 2) { - ands[i].a <== eq[k - 1].out; - ands[i].b <== lt[k - 2].out; - eq_ands[i].a <== eq[k - 1].out; - eq_ands[i].b <== eq[k - 2].out; - ors[i].a <== lt[k - 1].out; - ors[i].b <== ands[i].out; - } else { - ands[i].a <== eq_ands[i + 1].out; - ands[i].b <== lt[i].out; - eq_ands[i].a <== eq_ands[i + 1].out; - eq_ands[i].b <== eq[i].out; - ors[i].a <== ors[i + 1].out; - ors[i].b <== ands[i].out; - } - } - out <== ors[0].out; -} - - -/// @template CheckCarryToZero -/// @notice Check that in[] as a big integer is zero -/// @param n The number of bits in each chunk -/// @param m -/// @param k The number of chunks -/// @input in The input big integer; assumes elements to be in the range -2^(m-1) to 2^(m-1) -template CheckCarryToZero(n, m, k) { - assert(k >= 2); - - var EPSILON = 3; - - assert(m + EPSILON <= 253); - - signal input in[k]; - - signal carry[k]; - component carryRangeChecks[k]; - for (var i = 0; i < k-1; i++){ - carryRangeChecks[i] = Num2Bits(m + EPSILON - n); - if( i == 0 ){ - carry[i] <-- in[i] / (1<> (i - msgLen)) & 1; - } - - component modulusZero[(n*k + 7 - (baseLen + 8))\8]; - { - var modulusPrefix = 0; - for (var i = n*k - 1; i >= baseLen + 8; i--) { - if (i+8 < n*k) { - modulusPrefix += modulusBits[i+8]; - if (i % 8 == 0) { - var idx = (i - (baseLen + 8)) \ 8; - modulusZero[idx] = IsZero(); - modulusZero[idx].in <== modulusPrefix; - paddedMessageBits[i] <== 1-modulusZero[idx].out; - } else { - paddedMessageBits[i] <== paddedMessageBits[i+1]; - } - } else { - paddedMessageBits[i] <== 0; - } - } - } - - // The RFC guarantees at least 8 octets of 0xff padding. - assert(baseLen + 8 + 65 <= n * k); - - for (var i = baseLen + 8; i < baseLen + 8 + 65; i++) { - paddedMessageBits[i] === 1; - } - - component passedMessageB2N[k]; - for (var i = 0; i < k; i++) { - passedMessageB2N[i] = Bits2Num(n); - for (var j = 0; j < n; j++) { - passedMessageB2N[i].in[j] <== paddedMessageBits[i*n+j]; - } - out[i] <== passedMessageB2N[i].out; - } -} diff --git a/circuits/circuits/utils/zkemail/lib/sha.circom b/circuits/circuits/utils/zkemail/lib/sha.circom deleted file mode 100644 index 5ed154ea..00000000 --- a/circuits/circuits/utils/zkemail/lib/sha.circom +++ /dev/null @@ -1,292 +0,0 @@ -pragma circom 2.1.6; - -include "circomlib/circuits/bitify.circom"; -include "circomlib/circuits/sha256/constants.circom"; -include "circomlib/circuits/sha256/sha256compression.circom"; -include "circomlib/circuits/comparators.circom"; -include "./fp.circom"; -include "../utils/array.circom"; -include "../utils/functions.circom"; - - -/// @title Sha256Bytes -/// @notice Computes the SHA256 hash of input bytes -/// @input paddedIn Message to hash, padded as per the SHA256 specification; assumes to consist of bytes -/// @input paddedInLength Length of the padded message; assumes to be in `ceil(log2(8 * maxByteLength))` bits -/// @output out The 256-bit hash of the input message -template Sha256Bytes(maxByteLength) { - signal input paddedIn[maxByteLength]; - signal input paddedInLength; - signal output out[256]; - - var maxBits = maxByteLength * 8; - component sha = Sha256General(maxBits); - - component bytes[maxByteLength]; - for (var i = 0; i < maxByteLength; i++) { - bytes[i] = Num2Bits(8); - bytes[i].in <== paddedIn[i]; - for (var j = 0; j < 8; j++) { - sha.paddedIn[i*8+j] <== bytes[i].out[7-j]; - } - } - sha.paddedInLength <== paddedInLength * 8; - - for (var i = 0; i < 256; i++) { - out[i] <== sha.out[i]; - } -} - - -/// @title Sha256BytesPartial -/// @notice Computes the SHA256 hash of input bytes with a precomputed state -/// @input paddedIn Message to hash padded as per the SHA256 specification; assumes to consist of bytes -/// @input paddedInLength Length of the padded message; assumes to be in `ceil(log2(8 * maxByteLength))` bits -/// @input preHash The precomputed state of the hash -/// @output out SHA hash the input message with the precomputed state -template Sha256BytesPartial(maxByteLength) { - assert(maxByteLength % 32 == 0); - - signal input paddedIn[maxByteLength]; - signal input paddedInLength; - signal input preHash[32]; - signal output out[256]; - - var maxBits = maxByteLength * 8; - component sha = Sha256Partial(maxBits); - - component bytes[maxByteLength]; - for (var i = 0; i < maxByteLength; i++) { - bytes[i] = Num2Bits(8); - bytes[i].in <== paddedIn[i]; - for (var j = 0; j < 8; j++) { - sha.paddedIn[i*8+j] <== bytes[i].out[7-j]; - } - } - sha.paddedInLength <== paddedInLength * 8; - - component states[32]; - for (var i = 0; i < 32; i++) { - states[i] = Num2Bits(8); - states[i].in <== preHash[i]; - for (var j = 0; j < 8; j++) { - sha.preHash[8*i+j] <== states[i].out[7-j]; - } - } - - for (var i = 0; i < 256; i++) { - out[i] <== sha.out[i]; - } -} - - -/// @title Sha256General -/// @notice A modified version of the SHA256 circuit that allows specified length messages up to a -/// max to all work via array indexing on the SHA256 compression circuit. -/// @input paddedIn Message to hash padded as per the SHA256 specification; assumes to consist of bits -/// @input paddedInLength Length of the padded message; assumes to be in `ceil(log2(maxBitLength))` bits -/// @output out The 256-bit hash of the input message -template Sha256General(maxBitLength) { - // maxBitLength must be a multiple of 512 - // the bit circuits in this file are limited to 15 so must be raised if the message is longer. - assert(maxBitLength % 512 == 0); - - var maxBitsPaddedBits = log2Ceil(maxBitLength); - - // Note that maxBitLength = maxBits + 64 - signal input paddedIn[maxBitLength]; - signal input paddedInLength; - - signal output out[256]; - - signal inBlockIndex; - - var i; - var k; - var j; - var maxBlocks; - var bitsLastBlock; - maxBlocks = (maxBitLength\512); - - inBlockIndex <-- (paddedInLength >> 9); - paddedInLength === inBlockIndex * 512; - - // These verify the unconstrained floor calculation is the uniquely correct integer that represents the floor - // component floorVerifierUnder = LessEqThan(maxBitsPaddedBits); // todo verify the length passed in is less than nbits. note that maxBitsPaddedBits can likely be lowered or made it a fn of maxbits - // floorVerifierUnder.in[0] <== (inBlockIndex)*512; - // floorVerifierUnder.in[1] <== paddedInLength; - // floorVerifierUnder.out === 1; - - // component floorVerifierOver = GreaterThan(maxBitsPaddedBits); - // floorVerifierOver.in[0] <== (inBlockIndex+1)*512; - // floorVerifierOver.in[1] <== paddedInLength; - // floorVerifierOver.out === 1; - - // These verify we pass in a valid number of bits to the SHA256 compression circuit. - component bitLengthVerifier = LessEqThan(maxBitsPaddedBits); // todo verify the length passed in is less than nbits. note that maxBitsPaddedBits can likely be lowered or made it a fn of maxbits - bitLengthVerifier.in[0] <== paddedInLength; - bitLengthVerifier.in[1] <== maxBitLength; - bitLengthVerifier.out === 1; - - // Note that we can no longer do padded verification efficiently inside the SHA because it requires non deterministic array indexing. - // We can do it if we add a constraint, but since guessing a valid SHA2 preimage is hard anyways, we'll just do it outside the circuit. - - // signal paddedIn[maxBlocks*512]; - // for (k=0; k> k)&1; - // } - - 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 sha256compression[maxBlocks]; - - for (i=0; i> 9); - paddedInLength === inBlockIndex * 512; - - // These verify we pass in a valid number of bits to the SHA256 compression circuit. - component bitLengthVerifier = LessEqThan(maxBitsPaddedBits); // todo verify the length passed in is less than nbits. note that maxBitsPaddedBits can likely be lowered or made it a fn of maxbits - bitLengthVerifier.in[0] <== paddedInLength; - bitLengthVerifier.in[1] <== maxBitLength; - bitLengthVerifier.out === 1; - - component sha256compression[maxBlocks]; - - for (i=0; i= end); - assert(start >= 0); - assert(end >= start); - - signal input in[n]; - signal output out[end - start]; - - for (var i = start; i < end; i++) { - out[i - start] <== in[i]; - } -} - -/// @title CheckSubstringMatch -/// @notice Check if a substring matches the input array -/// @param maxSubstringLen The maximum length of the substring -/// @input input The portion of the input array to check -/// @input substring The substring pattern to match -/// @output isMatch 1 if the substring matches, 0 otherwise -template CheckSubstringMatch(maxSubstringLen) { - signal input in[maxSubstringLen]; - signal input substring[maxSubstringLen]; - signal output isMatch; - - // Ensure the first element of the pattern is non-zero - signal firstElementNonZero; - firstElementNonZero <== IsZero()(substring[0]); - firstElementNonZero === 0; - - signal matchAccumulator[maxSubstringLen + 1]; - signal difference[maxSubstringLen]; - signal isZeroDifference[maxSubstringLen]; - - matchAccumulator[0] <== 1; - - for (var i = 0; i < maxSubstringLen; i++) { - difference[i] <== (in[i] - substring[i]) * substring[i]; - isZeroDifference[i] <== IsZero()(difference[i]); - matchAccumulator[i + 1] <== matchAccumulator[i] * isZeroDifference[i]; - } - - isMatch <== matchAccumulator[maxSubstringLen]; -} - -/// @title CountSubstringOccurrences -/// @notice Count the number of times a substring occurs in the input array -/// @param maxLen The maximum length of the input array -/// @param maxSubstringLen The maximum length of the substring -/// @input in The input array to search in -/// @input substring The substring to search for -/// @output count The number of occurrences of the substring in the input -template CountSubstringOccurrences(maxLen, maxSubstringLen) { - assert(maxLen >= maxSubstringLen); - - signal input in[maxLen]; - signal input substring[maxSubstringLen]; - signal output count; - - // Check for matches at each possible starting position - component matches[maxLen]; - for (var i = 0; i < maxLen; i++) { - matches[i] = CheckSubstringMatch(maxSubstringLen); - for (var j = 0; j < maxSubstringLen; j++) { - if (i + j < maxLen) { - matches[i].in[j] <== in[i + j]; - } else { - matches[i].in[j] <== 0; - } - } - matches[i].substring <== substring; - } - - // Sum up all matches to get the total count - component summer = CalculateTotal(maxLen); - for (var i = 0; i < maxLen; i++) { - summer.nums[i] <== matches[i].isMatch; - } - - count <== summer.sum; -} \ No newline at end of file diff --git a/circuits/circuits/utils/zkemail/utils/bytes.circom b/circuits/circuits/utils/zkemail/utils/bytes.circom deleted file mode 100644 index 2bc0c1cf..00000000 --- a/circuits/circuits/utils/zkemail/utils/bytes.circom +++ /dev/null @@ -1,185 +0,0 @@ -pragma circom 2.1.6; - -include "circomlib/circuits/bitify.circom"; -include "circomlib/circuits/comparators.circom"; -include "./array.circom"; -include "./constants.circom"; -include "./functions.circom"; - - -function computeIntChunkLength(byteLength) { - var packSize = MAX_BYTES_IN_FIELD(); - - var remain = byteLength % packSize; - var numChunks = (byteLength - remain) / packSize; - if (remain > 0) { - numChunks += 1; - } - - return numChunks; -} - - -/// @title PackBytes -/// @notice Pack an array of bytes to numbers that fit in the field -/// @param maxBytes the maximum number of bytes in the input array -/// @input in the input byte array; assumes elements to be bytes -/// @output out the output integer array -template PackBytes(maxBytes) { - var packSize = MAX_BYTES_IN_FIELD(); - var maxInts = computeIntChunkLength(maxBytes); - - signal input in[maxBytes]; - signal output out[maxInts]; - - signal intSums[maxInts][packSize]; - - for (var i = 0; i < maxInts; i++) { - for(var j=0; j < packSize; j++) { - var idx = packSize * i + j; - - // Copy the previous value if we are out of bounds - we take last item as final result - if(idx >= maxBytes) { - intSums[i][j] <== intSums[i][j-1]; - } - // First item of each chunk is the byte itself - else if (j == 0){ - intSums[i][j] <== in[idx]; - } - // Every other item is 256^j * byte - else { - intSums[i][j] <== intSums[i][j-1] + (1 << (8*j)) * in[idx]; - } - } - } - - // Last item of each chunk is the final sum - for (var i = 0; i < maxInts; i++) { - out[i] <== intSums[i][packSize-1]; - } -} - - -/// @title PackByteSubArray -/// @notice Select sub array from the input array and pack it to numbers that fit in the field -/// @notice This is not used in ZK-Email circuits anywhere -/// @param maxArrayLen the maximum number of elements in the input array -/// @param maxSubArrayLen the maximum number of elements in the sub array -/// @input in the input byte array; assumes elements to be bytes -/// @input startIndex the start index of the sub array; assumes to be a valid index -/// @input length the length of the sub array; assumes to fit in `ceil(log2(maxSubArrayLen))` bits -/// @output out the output integer array -template PackByteSubArray(maxArrayLen, maxSubArrayLen) { - assert(maxSubArrayLen < maxArrayLen); - var chunkLength = computeIntChunkLength(maxSubArrayLen); - - signal input in[maxArrayLen]; - signal input startIndex; - signal input length; - - signal output out[chunkLength]; - - component SelectSubArray = SelectSubArray(maxArrayLen, maxSubArrayLen); - SelectSubArray.in <== in; - SelectSubArray.startIndex <== startIndex; - SelectSubArray.length <== length; - - component packer = PackBytes(maxSubArrayLen); - packer.in <== SelectSubArray.out; - - out <== packer.out; -} - - -/// @title DigitBytesToInt -/// @notice Converts a byte array representing digits to an integer -/// @notice Assumes the output number fits in the field -/// @param n The number of bytes in the input array -/// @input in The input byte array; assumes elements are between 48 and 57 (ASCII numbers) -/// @output out The output integer; assumes to fit in the field -template DigitBytesToInt(n) { - signal input in[n]; - - signal output out; - - signal sums[n+1]; - sums[0] <== 0; - - for(var i = 0; i < n; i++) { - sums[i + 1] <== 10 * sums[i] + (in[i] - 48); - } - - out <== sums[n]; -} - - -// NOTE: this circuit is unaudited and should not be used in production -/// @title SplitBytesToWords -/// @notice split an array of bytes into an array of words -/// @notice useful for casting a message or modulus before RSA verification -/// @param l: number of bytes in the input array -/// @param n: number of bits in a word -/// @param k: number of words -/// @input in: array of bytes -/// @output out: array of words -template SplitBytesToWords (l,n,k) { - signal input in[l]; - signal output out[k]; - - component num2bits[l]; - for (var i = 0 ; i < l ; i++){ - num2bits[i] = Num2Bits(8); - num2bits[i].in <== in[i]; - } - component bits2num[k]; - for (var i = 0 ; i < k ; i++){ - bits2num[i] = Bits2Num(n); - for(var j = 0 ; j < n ; j++){ - if(i*n + j >= 8 * l){ - bits2num[i].in[j] <== 0; - } - else{ - bits2num[i].in[j] <== num2bits[l - (( i * n + j) \ 8) - 1].out[ ((i * n + j) % 8)]; - } - } - } - for( var i = 0 ; i< k ; i++){ - out[i] <== bits2num[i].out; - } -} - -// Asserts that a given input is binary. -// -// Inputs: -// - in: an input signal, expected to be 0 or 1. -template AssertBit() { - signal input in; - in * (in - 1) === 0; -} - -// The ByteMask template masks an input array using a binary mask array. -// Each element in the input array is multiplied by the corresponding element in the mask array. -// The mask array is validated to ensure all elements are binary (0 or 1). -// -// Parameters: -// - maxLength: The maximum length of the input and mask arrays. -// -// Inputs: -// - body: An array of signals representing the body to be masked. -// - mask: An array of signals representing the binary mask. -// -// Outputs: -// - out: An array of signals representing the masked input. -template ByteMask(maxLength) { - signal input in[maxLength]; - signal input mask[maxLength]; - signal output out[maxLength]; - - component bit_check[maxLength]; - - for (var i = 0; i < maxLength; i++) { - bit_check[i] = AssertBit(); - bit_check[i].in <== mask[i]; - out[i] <== in[i] * mask[i]; - } -} \ No newline at end of file diff --git a/circuits/circuits/utils/zkemail/utils/constants.circom b/circuits/circuits/utils/zkemail/utils/constants.circom deleted file mode 100644 index 69b0c993..00000000 --- a/circuits/circuits/utils/zkemail/utils/constants.circom +++ /dev/null @@ -1,15 +0,0 @@ -pragma circom 2.1.6; - - -function EMAIL_ADDR_MAX_BYTES() { - return 256; -} - -function DOMAIN_MAX_BYTES() { - return 255; -} - -// Field support maximum of ~253 bit -function MAX_BYTES_IN_FIELD() { - return 31; -} diff --git a/circuits/circuits/utils/zkemail/utils/functions.circom b/circuits/circuits/utils/zkemail/utils/functions.circom deleted file mode 100644 index 7c76024f..00000000 --- a/circuits/circuits/utils/zkemail/utils/functions.circom +++ /dev/null @@ -1,17 +0,0 @@ -pragma circom 2.1.6; - -/// @function log2Ceil -/// @notice Calculate log2 of a number and round it up -/// @param a The input value -/// @return The result of the log2Ceil -function log2Ceil(a) { - var n = a - 1; - var r = 0; - - while (n > 0) { - r++; - n \= 2; - } - - return r; -} diff --git a/circuits/tests/dsc.test.ts b/circuits/tests/dsc.test.ts index b776f1da..e262bb7a 100644 --- a/circuits/tests/dsc.test.ts +++ b/circuits/tests/dsc.test.ts @@ -68,9 +68,9 @@ testSuite.forEach(({ sigAlg, hashFunction, domainParameter, keyLength }) => { ), { include: [ - // 'node_modules', - // './node_modules/@zk-kit/binary-merkle-root.circom/src', - // './node_modules/circomlib/circuits', + 'node_modules', + './node_modules/@zk-kit/binary-merkle-root.circom/src', + './node_modules/circomlib/circuits', ], } ); diff --git a/circuits/tests/prove.test.ts b/circuits/tests/prove.test.ts index 16505e11..520c0a92 100644 --- a/circuits/tests/prove.test.ts +++ b/circuits/tests/prove.test.ts @@ -79,7 +79,14 @@ testSuite.forEach(({ sigAlg, hashFunction, domainParameter, keyLength }) => { path.join( __dirname, `../circuits/prove/instances/${getCircuitName('prove', sigAlg, hashFunction, domainParameter, keyLength)}.circom` - ) + ), + { + include: [ + 'node_modules', + './node_modules/@zk-kit/binary-merkle-root.circom/src', + './node_modules/circomlib/circuits', + ], + } ); }); @@ -91,7 +98,7 @@ testSuite.forEach(({ sigAlg, hashFunction, domainParameter, keyLength }) => { const w = await circuit.calculateWitness(inputs); await circuit.checkConstraints(w); // circuits.getOutput takes way too long for ecdsa - if (sigAlg === 'ecdsa') { + if (true) { console.log('skipping printing outputs to console for ecdsa'); return; }