@ -0,0 +1,14 @@ |
|||
|
|||
include "compconstant.circom"; |
|||
|
|||
|
|||
template AliasCheck() { |
|||
|
|||
signal input in[254]; |
|||
|
|||
component compConstant = CompConstant(-1); |
|||
|
|||
for (var i=0; i<254; i++) in[i] ==> compConstant.in[i]; |
|||
|
|||
compConstant.out === 0; |
|||
} |
@ -0,0 +1,93 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
/* |
|||
|
|||
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<a) { |
|||
r++; |
|||
n *= 2; |
|||
} |
|||
return r; |
|||
} |
|||
|
|||
|
|||
template BinSum(n, ops) { |
|||
var nout = nbits((2**n -1)*ops); |
|||
signal input in[ops][n]; |
|||
signal output out[nout]; |
|||
|
|||
var lin = 0; |
|||
var lout = 0; |
|||
|
|||
var k; |
|||
var j; |
|||
|
|||
for (k=0; k<n; k++) { |
|||
for (j=0; j<ops; j++) { |
|||
lin += in[j][k] * 2**k; |
|||
} |
|||
} |
|||
|
|||
for (k=0; k<nout; k++) { |
|||
out[k] <-- (lin >> k) & 1; |
|||
|
|||
// Ensure out is binary |
|||
out[k] * (out[k] - 1) === 0; |
|||
|
|||
lout += out[k] * 2**k; |
|||
} |
|||
|
|||
// Ensure the sum; |
|||
|
|||
lin === lout; |
|||
} |
@ -0,0 +1,72 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
include "comparators.circom"; |
|||
|
|||
|
|||
template Num2Bits(n) { |
|||
signal input in; |
|||
signal output out[n]; |
|||
var lc1=0; |
|||
|
|||
for (var i = 0; i<n; i++) { |
|||
out[i] <-- (in >> 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<n; i++) { |
|||
lc1 += in[i] * 2**i; |
|||
} |
|||
|
|||
lc1 ==> out; |
|||
} |
|||
|
|||
template Num2BitsNeg(n) { |
|||
signal input in; |
|||
signal output out[n]; |
|||
var lc1=0; |
|||
|
|||
component isZero; |
|||
|
|||
isZero = IsZero(); |
|||
|
|||
var neg = n == 0 ? 0 : 2**n - in; |
|||
|
|||
for (var i = 0; i<n; i++) { |
|||
out[i] <-- (neg >> i) & 1; |
|||
out[i] * (out[i] -1 ) === 0; |
|||
lc1 += out[i] * 2**i; |
|||
} |
|||
|
|||
in ==> isZero.in; |
|||
|
|||
|
|||
|
|||
lc1 + isZero.out * 2**n === 2**n - in; |
|||
} |
@ -0,0 +1,55 @@ |
|||
include "bitify.circom"; |
|||
include "binsum.circom"; |
|||
|
|||
template IsZero() { |
|||
signal input in; |
|||
signal output out; |
|||
|
|||
signal inv; |
|||
|
|||
inv <-- in!=0 ? 1/in : 0; |
|||
|
|||
out <== -in*inv +1; |
|||
in*out === 0; |
|||
} |
|||
|
|||
|
|||
template IsEqual() { |
|||
signal input in[2]; |
|||
signal output out; |
|||
|
|||
component isz = IsZero(); |
|||
|
|||
in[1] - in[0] ==> isz.in; |
|||
|
|||
isz.out ==> out; |
|||
} |
|||
|
|||
|
|||
// N is the number of bits the input have. |
|||
// The MSF is the sign bit. |
|||
template LessThan(n) { |
|||
signal input in[2]; |
|||
signal output out; |
|||
|
|||
component num2Bits0; |
|||
component num2Bits1; |
|||
|
|||
component adder; |
|||
|
|||
adder = BinSum(n, 2); |
|||
|
|||
num2Bits0 = Num2Bits(n); |
|||
num2Bits1 = Num2BitsNeg(n); |
|||
|
|||
in[0] ==> num2Bits0.in; |
|||
in[1] ==> num2Bits1.in; |
|||
|
|||
var i; |
|||
for (i=0;i<n;i++) { |
|||
num2Bits0.out[i] ==> adder.in[0][i]; |
|||
num2Bits1.out[i] ==> adder.in[1][i]; |
|||
} |
|||
|
|||
adder.out[n-1] ==> out; |
|||
} |
@ -0,0 +1,56 @@ |
|||
|
|||
include "bitify.circom"; |
|||
|
|||
// Returns 1 if in (in binary) > ct |
|||
|
|||
template CompConstant(ct) { |
|||
signal input in[254]; |
|||
signal output out; |
|||
|
|||
signal parts[127]; |
|||
signal sout; |
|||
|
|||
var clsb; |
|||
var cmsb; |
|||
var slsb; |
|||
var smsb; |
|||
|
|||
var sum=0; |
|||
|
|||
var b = (1 << 128) -1; |
|||
var a = 1; |
|||
var e = 1; |
|||
var i; |
|||
|
|||
for (i=0;i<127; i++) { |
|||
clsb = (ct >> (i*2)) & 1; |
|||
cmsb = (ct >> (i*2+1)) & 1; |
|||
slsb = in[i*2]; |
|||
smsb = in[i*2+1]; |
|||
|
|||
|
|||
if ((cmsb==0)&(clsb==0)) { |
|||
parts[i] <== -b*smsb*slsb + b*smsb + b*slsb; |
|||
} else if ((cmsb==0)&(clsb==1)) { |
|||
parts[i] <== a*smsb*slsb - a*slsb + b*smsb - a*smsb + a; |
|||
} else if ((cmsb==1)&(clsb==0)) { |
|||
parts[i] <== b*smsb*slsb - a*smsb + a; |
|||
} else { |
|||
parts[i] <== -a*smsb*slsb + a; |
|||
} |
|||
|
|||
sum = sum + parts[i]; |
|||
|
|||
b = b -e; |
|||
a = a +e; |
|||
e = e*2; |
|||
} |
|||
|
|||
sout <== sum; |
|||
|
|||
component num2bits = Num2Bits(135); |
|||
|
|||
num2bits.in <== sout; |
|||
|
|||
out <== num2bits.out[127]; |
|||
} |
@ -1,14 +1,9 @@ |
|||
include "../node_modules/circom/circuits/compconstant.circom"; |
|||
include "compconstant.circom"; |
|||
include "pointbits.circom"; |
|||
include "pedersen.circom"; |
|||
include "escalarmulany.circom"; |
|||
include "escalarmulfix.circom"; |
|||
|
|||
/* |
|||
include "../node_modules/circom/circuits/bitify.circom"; |
|||
include "babyjub.circom"; |
|||
*/ |
|||
|
|||
template EdDSAVerifier(n) { |
|||
signal input msg[n]; |
|||
|
@ -0,0 +1,67 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
template XOR() { |
|||
signal input a; |
|||
signal input b; |
|||
signal output out; |
|||
|
|||
out <== a + b - 2*a*b; |
|||
} |
|||
|
|||
template AND() { |
|||
signal input a; |
|||
signal input b; |
|||
signal output out; |
|||
|
|||
out <== a*b; |
|||
} |
|||
|
|||
template OR() { |
|||
signal input a; |
|||
signal input b; |
|||
signal output out; |
|||
|
|||
out <== a + b - a*b; |
|||
} |
|||
|
|||
template NOT() { |
|||
signal input in; |
|||
signal output out; |
|||
|
|||
out <== 1 + in - 2*in; |
|||
} |
|||
|
|||
template NAND() { |
|||
signal input a; |
|||
signal input b; |
|||
signal output out; |
|||
|
|||
out <== 1 - a*b; |
|||
} |
|||
|
|||
template NOR() { |
|||
signal input a; |
|||
signal input b; |
|||
signal output out; |
|||
|
|||
out <== a*b + 1 - a - b; |
|||
} |
|||
|
|||
|
@ -0,0 +1,286 @@ |
|||
|
|||
|
|||
|
|||
|
|||
template MiMC7(nrounds) { |
|||
signal input x_in; |
|||
signal input k; |
|||
signal output out; |
|||
|
|||
var c = [ |
|||
0x0000000000000000000000000000000000000000000000000000000000000000, |
|||
0x2573c33972da08a17b379c84ef2ac8f5b1da7feb7a0f65820f5106065947e745, |
|||
0x21ac176a3dfade8c2846270deb9bda2c1fa8fe29504ed1abef144ae541da6fb0, |
|||
0x1fcd4c98bb955979dfaebd9403cc2dd58025fc615a06014feaa543fc9565b744, |
|||
0x1899ead9379f4e15c5468c709087eeaa61fa8efa361a71dac432c6145bb20d63, |
|||
0x1b82d1cfcf057d24682f9cc3aab8fcdb35129359b5ba5578eb0fb20885c7c261, |
|||
0x3023bd978dce3b40760481f90709bfd4b1894665493edc70f0890dd0817ab973, |
|||
0x217a46b7998bbd8ce17073e7296cef81681da9dc4ca055abaf28345f8bf0cbe7, |
|||
0x1614c499d51b5125df6214f41cd51ac79e07565171758d80b091b9a3029a5422, |
|||
0x05dfffcee509e641a30504f9c239340af6cd43cc6b7f03feb65235c4b9bccd86, |
|||
0x248d5e6f74e607401c9bdc79bd5d2e899028fc26e7db9437c7738e60b7a90b37, |
|||
0x0dd9d1bbccd01bb58caf364938ccc55e74953f0ae52ee145beaecbfbe683e777, |
|||
0x0bd18dd6afccd76ae3a159cac4bb1ec1158def927f5b8a529a4697ba3294805b, |
|||
0x00ce7b4a2643c23fab142b955293492bda5b775cea46ef3e9bc803301935d987, |
|||
0x24927ca97213de091fac3153a76dd4dd6c9933b1bc298148ece271dd80623f8d, |
|||
0x035e884c65a79c58a895b27d4ef671b1661dac72281f4c4458ae2a0be14c4555, |
|||
0x008427f6c5e2fa34dc787fcef8cdf0ae2b5686cb80cc069a59a9b8af37ec0d42, |
|||
0x01e0bf5c000e7390c86635a3d63c2b42362c2f43f8ea2cdfab4728f901443dc1, |
|||
0x05e5f9e17e59bb89922f0c52aaef5728129fe284e4c2cea2b3f50d9f1bf04280, |
|||
0x1ed43af042061416a934f6d4afe097b32b42a916075441fbaf2016405a03121c, |
|||
0x05c2929b4c8610d3f2bbc7f0d8046937feb4bdfaca9d6e1434aab696950f0d94, |
|||
0x0f5df25a785d5fdfaede0ff3e0853a35f66c8b140ca82b1c7648a1496ba902cd, |
|||
0x1d9177a9c7d2cbcdc6bf2ce3bdb93066598c0c00096084f32a08c00065fcb640, |
|||
0x0ad36f853cb652ca4d8c87d3a64a2a9f7dd849d5f6dbced160001672661f0257, |
|||
0x061d5c826fb0716891996013195a349f17e89197e1e0b0826ba0bb3a69ba42e2, |
|||
0x16603fd47dcb9c87f50541b78211b9d5f57ef5536d888efa4f626e2fbf239089, |
|||
0x056cee578203bca4df16a390cfa63e85931e6e78d300d8b61128d37028d45813, |
|||
0x1243ed309d9d4e9371159fb9f9a3245a4cc00b36954bff7c7da88b6c476752cf, |
|||
0x0ad05b9f6ac744163ceb578e4dc7fd79415e038284e72ee9725dad919f4ddacb, |
|||
0x0e9feebe1c929460bfb50e7b2055f342858e7f1390e85a117cd0259d3e9d1ed3, |
|||
0x290888d2474655e8348a0dc2f3c663ff488390ac2ffb8616b8989622cf5e45de, |
|||
0x1ea4564ef6a12b38236cef7ff9638ace2feb8620d6fc43f00899db7d8857d665, |
|||
0x0a88eb25fd9e1853a6fb3be2a64d7833d08d6bb471c062f81abd8b83cf1ac184, |
|||
0x24b95adf13d6e7cddac8aa314cdbc7919e129d2ff4fe25f0e13850b3c355aa49, |
|||
0x0e8be6948bcc439176fdf51e97933bd4d9aecf6c2a229e10726a941eab8035f3, |
|||
0x0576ca71206b818ec4fe2c114b1385cb45b0c75a4264344102aacdb1dc75c40d, |
|||
0x1127019d23d0e8c78a5c920422417be24242f5361b5b9b4c65673c3ca6f5c877, |
|||
0x03308b8e26f82269cc957ce50c9025bfb1bcadf536e73fcbb3755b31d274c1c7, |
|||
0x2946f2c0596dffcdc46c9f149b53ee838f37479d156ba9cec0956c6647d632f8, |
|||
0x02f45b1bf152730a9e598de1cfd6dd29673341513a702563b415c5c71accf46e, |
|||
0x0f0080f25c9a57ec936c87c99c2ab62f63a5b315dae3351f095ee2fa4be67e1f, |
|||
0x0d90b434ba57abe6b35c15ae3652f730732714372fc7a97e2c02088856d62014, |
|||
0x1865dafc3484c977adfa0aaf7c67af83db678adbcde788fb0d3d24891a17cc0c, |
|||
0x12ed55fd63570eab6520dfa5cfad9966f2adcceb4eec664f4e4a071d5d70b82e, |
|||
0x19b0bb01d39832937c9da2bd1acb87446db2e30c7170cbfa403d6431e6053a62, |
|||
0x1906ec1e76ad9371267a5a206e38b76d446a868c9be4be98a234910865e1b877, |
|||
0x23f62fe89f2a36259878a077482a5f6ff85740e5d8f9d9ffacbb9263b18a86af, |
|||
0x2f4b20c57d3038c70271187292b4a94e56019730dcfdee59ad28bf2371f89b73, |
|||
0x2188c593ba388bb539b6a3e89cf9eec31520abc006e25b21ef0b9ec0ba795ead, |
|||
0x19f9d9dccd162b2c6132a1ad6eb0bb693540838aeeb50ff9cd78fd2e70f2539d, |
|||
0x0a459c91a19aab5685a042bf3310782d078934c7bcbea3ddbccee2dd5d1d0ae4, |
|||
0x12677a533b2dc95d090c277d3076a99a3555dbdee415667fe6ddd91419836801, |
|||
0x08bef6949f3fb6e74f0f1b5b2b414bbbdee5871055b533b973b299419af4fafc, |
|||
0x14ba2da4075ea3c3422f12d6d2b2753caf962f80bef50bb246e6a3f58999317b, |
|||
0x2ca11bf0295867199deb7681e102f655079722dfd08e55b5897c9f0461307d8c, |
|||
0x2b59a960a82ae74b6f33ceff6ad156bf7f0c8989ce351bce650e9d5e5c05a3ac, |
|||
0x013235db83fed0cf34a42d87ea9e662fbd700eae3174a4bf07f4f0e541ba4c98, |
|||
0x014081d1be424ddcfa6e71181af3a4efaf7b7f7dfdb78788f106170bbfc6c458, |
|||
0x021b8e121f282676a983b9a3a5d18fc33e6080afe3824cf82a0d527e5f92be3e, |
|||
0x25da0ea238d74268ea3df1b43f15145d7d1b7984560c9b96ecdb92a7c154c0fc, |
|||
0x223b40a33fd0c17b639bd1c44b2cd66214a31791b42ab5605d253bd043112c78, |
|||
0x24e8c7cc3a48d2472b27a165590bfe81bc8f0560b1ec7c8a2dcebc8e088255f6, |
|||
0x203df46cb4b2681cdf63d8bc380f696b852b076a0788456e52f980cb39406b56, |
|||
0x102171b10649730b641ad5fca7509a8be02617e64b6a2c530f8dfcb96381d8fb, |
|||
0x21483341bf6330c095667236cb25c2fb795950be20db2993d00f95e9db86d548, |
|||
0x0b01bfd7cd717115b6b9f104d4d75da9a48cc0d84ab5c97d2b33254192bc4003, |
|||
0x2ea24cc861e05aebbe83fa8f2d75443ea497101032c1d9c0bd1a23861c8864ed, |
|||
0x04372690ea0d050a30f2c25d0ce905916b435eb5fc81c9c759edbf45107a8d85, |
|||
0x051ee6ddc890879beccdf7178672856cff03f1462c6227e57950fa5888fc6fd5, |
|||
0x1d57b69d317b1c45b61a53f963282305293eb647f29e776700655830e0e70614, |
|||
0x2fbd442d418657365ff66249f800158dae372a9b80b5939c7872e73cbfb06df9, |
|||
0x26f45b678433c5787d044a18a0bd60bb9434b4db98cb6b32c37ff5bc42b6e290, |
|||
0x0a0b76699ae7b56e0b819136a3a5badc4ca25b67edbd3d19f2c77542fb77f90a, |
|||
0x25f6a09fef3227202e1166260c94310c9ef9eea578a8b7986010951bdbc9d9e0, |
|||
0x0d21807eda562f2939928a7e21168e2458d97219c521e3b7ea73cef17f74f6c3, |
|||
0x2d97038dd52fc0d78fd61b1a12b8b5b8125a5515b72b0f36413392b5f06d26b8, |
|||
0x1f207513cafcfe669a7e3c7c46cfbecfe21d89072dd56231a7084e52607852d4, |
|||
0x226f83c016c2dcbc3a5d8c5799309ac7a995b450cab5d5d159c12a3536972cca, |
|||
0x081541ea31c74625d97d43fa971a1c51906b245f097e9f283a8d2119b9779467, |
|||
0x297dcdcfdb36b89b2c046d650e21b611738780776bc135512a490b1c8ce15e14, |
|||
0x2d617064044226599099fd5bbaa46de5db333365ded2acdbd22e39d7812880cb, |
|||
0x0fbe2fcdbe3a75f13235d1b450aedfaeeb3ab5cc8d5a1f635e2ed543d6df94b6, |
|||
0x2fc42a33bd8bc618576cdf920700a758d10ddf00a9ecdda6e6cf2245a99be703, |
|||
0x304b634102263d927acda39750beabcf6e4da71dfe8fd057fb65b416d4240381, |
|||
0x072eaeea0b3f4a6308fe024a62e958a00063a2783d5c95f8662254e0d7bdad31, |
|||
0x12dd36ba1c45d2859450ece52afaceb6fc4eafd5d22e981534c11b800af49622, |
|||
0x16592d9f596f8e7db1195b598c9a5ab550ce58db40a3e01771a4b92f4447407f, |
|||
0x1cde4e85920302e735f5ae8ab90cdfe9f291bd6333277b28f99a23d2768e164b, |
|||
0x090b13387c1e63908026da15e43e91f4d7e046d11a7f2e19c11adb804b2e834f, |
|||
0x2fbccbb27a0fdebc61bdd69d766303495d4661a4535dea0cfd0f7c978da0aae8, |
|||
0x26a9feed3a8e11a6b42ce9c9dfc1dc0fa01f9f9748e672056aee55943b617950, |
|||
0x0a93928c9eacdfec490adcedeff1d4864e1770e48df6665ddfc3595fb26e73a9, |
|||
0x04ffe5957639c3155892d3c5812236d688c2c4d142f8c8feba1be04aacbb9f0a, |
|||
0x114b0e6b5a2bbfc49cd03f3a0e8a8afd263d9361ce3631b352f87d3f3090f968, |
|||
0x20e9116c087ae3c97f130ae383d8a18c7421608e76cca8c2f4a51bbe3735f8ca, |
|||
0x0b4af594cf9b1d509214dc943a94edb449416cae97408e72f1fe2990b4213c18, |
|||
0x0e9af7c41aa75f036b67dd6f1e741d8e55792777a08d68b2fd0a5c8b03ca1d37, |
|||
0x28964cd6cb5113ba250e6d4993c9a76e4333b961657eec7fe1987fad1482a795, |
|||
0x22b3e76214c678461c1b1176025e273fd8bc8eeb251eafacc9274198aa979467, |
|||
0x2d4382055d99f2fb3107682ccd712d9ddd834ae6006740b7ff53a47674d6426b, |
|||
0x2f276050872b35b18e0d21ae6c5a979cfbdff6f88f8725f925be61c2efbadaeb, |
|||
0x047923ac3092cd3b292535059b9ad97b9d74c38e552326b35df34bf10548fee0, |
|||
0x2d3d346b809cdcb8d9d34eab9c7b54a7f92bcefe01129ea97ab04a800453937c, |
|||
0x0c36a5b386d0b2f14728ed12c0cda1466f6e28a2b1626e7ece1d11a921695a31, |
|||
0x1aef33f82b69dfc7e51f5b647fd93e39cd81b100bc36620fa676eb57b64771da, |
|||
0x1a101b37be684aa86df8be0545043e33c0b86aa5930d94ac71306f99f00add35, |
|||
0x0626cddb01a255c1274a35b9842b1ece727ee158981d36bb17d17023bdf0ca15, |
|||
0x166f76eb2cdad17b7e1b4aad949b117310ef06b945c09d9bed79d9560cc3cd1e, |
|||
0x1aa6ae14d82811c36fce8923a0e9632e0b320505d135fe8df7d6dce57212a69c, |
|||
0x1e3332f6c23a8c0ceb3417e68c92261c5c005c43b9a676fa7019e95b9983e40f, |
|||
0x18f23783cbbcad4f561c9239314d6866c0a92eac0c53f9732ce8748aacc64ae9, |
|||
0x111d3bc2fc48feb3474865322c695ea5eaa6bebbd6da0c381920bc2d00e99776, |
|||
0x23b009813f17fd7138fb74df56c3247ef031ca124aa75d6ce4a8db63fef9c54d, |
|||
0x28ae7ec0874ce406eefa32e96b84aa77057c351b3f3aea6e8005d3b65ce6309c, |
|||
0x05a2d755f5e520b53b2765bfed7ccc7090cd5b2155460148ea73fd7eb7f89f9e, |
|||
0x100022a693424e0b0213f4992ed3d53334f9e1997825c86532b44a234523f6d4, |
|||
0x2d0c51264d581af3a64cfc0a5ca2eeaf6521a2d6100f4c323fb1ba6503303a42, |
|||
0x02ef717f6ac82e29b261aa0b28188ec299585edd9823847f900d36507f8194d8, |
|||
0x11b7074ac17782921a05a998d52ea6079628692bee9846bb03eb8e11ce802360, |
|||
0x14cee5e6d15a6c706654e7b5b0d350748c90f9b48fdde11d5e04c7cdb21864c7, |
|||
0x1183348c529c73a33319edd671e99991614fcc663d458b1c22e1677b6aebf924, |
|||
0x2325e0728102551f9fdf661e3459eb70c4dd5d3985f685e206b64b41cecd44eb, |
|||
0x20c1eab09b138e3653be1f4909c4cc5ec0a697eae83b6e926b78f81779d24911, |
|||
0x11c9e1d7edfd62875d01d773152203c4524b33d118f83b169ad1aed293d81b19, |
|||
0x070c9ff7fa280e4055a23e8bc9f6c317d2ac3221d2990e8accdf8c84cffc1e2f, |
|||
0x254af914dd424ceeb5438a50c61f50c7f56136da4615cfab12e61a5db6cff638, |
|||
0x28fb40fb9f010d97ddc38071fe5207fb78797ca71f534ccbc2bbdf6c115a4d16, |
|||
0x2d4c3d71cdf56c3d5956c6b4f6d5e855562f1794311e172a55294b6bbd7eb9e1, |
|||
0x1ace5d5fd5fc6b15f0b359d46171a9a92bc0190cf2dca0dbdac5a96a9b31ce17, |
|||
0x2b481ad328c016e5e0dd9a5be16da951b70af7dced31f7899cad9aebd251e78b, |
|||
0x173a51b6fd6ebccf78666457f4ca4d64023fc2e83540e17cb7ca12fa85869172, |
|||
0x139e2b576a2e5491952e78bb78065545f6f0e3a8c9b8519770c486cf92698e7f, |
|||
0x1bea94b6c53410f9112a63c2fddbe7eced47f17405c2db63db1b7051559b8109, |
|||
0x1d1c53d42e47093d961525be7c19d765cb2d43228a863edf220a7f6f38501a27, |
|||
0x2a91572dcc79f87408894c8d360b93cd9a5d8042b9d72b48c18838bd6fec0667, |
|||
0x269d5f30f099282511c4eccd423d5f3d64e2f8153a3e1fdedcc1d476fbd02ec8, |
|||
0x1950225dc9af9cccb17ccb8a9227a7384a78d93bd40bad6e9eec430416cc45c3, |
|||
0x20d36ac727d921193d4a2a45fbe123170ffb83e8f23fb4948215e7b8881e4bee, |
|||
0x18f4c2af29258c0dc4f14b1f538a3503b57f444c467520da8b047fa398062f31, |
|||
0x2bf4dcfbd1dbfdd6d6f08b43c4aee9818c915589105d33d6088cfe27921e5279, |
|||
0x191ed15cd07da3cdf8dbdea430c203fdffe64c01c7bb38053d11da051836ff91, |
|||
0x0eb85c12fefbee535e54702aff8ed5e6b6b3431a07d7473a1f20630672bb177d, |
|||
0x0e9d55dddb28d570572ed245a163ac213b281774e8f1ae82bca0c43263a30f08, |
|||
0x0001a2000bed5bea95515b5da6c8fdcb359a1f06f952313acff9c899b40dac23, |
|||
0x15fa1f0c3855cb2de7fc732236d310474c7995230f80d1112f19a407bf42bed7, |
|||
0x150c310e70221783e2042d1fc3824c19421a46ce668fdcda3b16db0af86845b7, |
|||
0x1e054c1bb6c893e1e104662de7b1275ae1dee43ca17e8f16ee093b4894f3440b, |
|||
0x16c9b293066013054c9979c8d046d1f20a41364fcc64186eeb2a98b3026857f3, |
|||
0x2ca9b4bb10dc2c1d0186e6bb50876dcf510c70629c6bf8481db3a830dfd7b15c, |
|||
0x2be7e344645273fab7c289ed00ba62f5d272ffdedcb0ec1d4e0a4d42902c8ef7, |
|||
0x187681a205e2b817fce1590ffd8e71bc2b7e3029d9053170af0c3d4f23b0b076, |
|||
0x041e20737b8c090cf62e341f3339515ec3fc886cf7b2ccd61738c8801fd74dcd, |
|||
0x109f5415950efdbf4c7162646e46ac7eb04b8ed8ac1eb52f34c8dd5b1d40f2b0, |
|||
0x2caa2202f0f455109e092b0581d5aa71c7c500831a217a1ccba50d9dade9c667, |
|||
0x2d4c3333cf741e7c0b86ac0f962368322704d1e09c0212181c82eb62ca426ae6, |
|||
0x15704173948ee1c2ff0072e43a8da316d50a7d59c0e47e0d6d045fce33d251cb, |
|||
0x1b7beea1f3d1073553d6a0756ff8be081b3a4ed4bc882927faf1e298a159ed28, |
|||
0x28a5660731ec0e6658d707a7426b44ee10a8d977131c6d9573da6c78fc813946, |
|||
0x1c25e36d652690ba17330b8f416f0de50a118087e8683418dc566a1317fb0d57, |
|||
0x0560867e3051cb4a1abfb67dc385ddf9bbc2c66afc78ef1c7be32cc5bb26ee5c, |
|||
0x020d0d9f2151ed7330fc4cacbb9b6d95ed0c914739cf0411256254424bbc105c, |
|||
0x00ce7eb2024c8a6e75097583cb82de4058f87d46f2709bebf26e6ebae3e8f136, |
|||
0x04d78c43b841fff58081606a44fdefde0aea13c52cc3387527b22d2205b843b5, |
|||
0x2259d75915d33431cd5aad3b0d90f0069197e190113ee3ad2c99f0e2b3f72195, |
|||
0x178df288dc79e1c87e5f052da31c98b3bfb533721923b7e3869c2112e7e85326, |
|||
0x11d668d143812697fd24ef1a20103b6c76339f652080fa63742802c1ecdcf0de, |
|||
0x0cdc41f4f4042ce1c5db5bb57972bf5594ace8acdd18017319e6b2cb658088b6, |
|||
0x1a54ebce705e92e10f7f665b3cbc66007c9d30da4a94926642dd7fceffeda68f, |
|||
0x279a8f5f37202edab28c806177a0ad8c2ddb65431b8187f5ea77fb192e1cc93d, |
|||
0x110f2b2bbfa6c4cbcdb3ae38931c217eb0d57c8657d5030cd774b421f057658e, |
|||
0x286352ab3c8d4acac74af412e2653056ae23a8d6e79b57cf5c4e9e89c0461c7f, |
|||
0x22aaf44d434a8c6947615bf82c5f48018174cbd10b8318418e20a1ab80fbb3a5, |
|||
0x082066e1285be2fd943557f5759e60210a5e7df9f555e1d3d5b11a0245099143, |
|||
0x03aeb70346c3d88d586efcace591ff711b2f4545729a1e8fe6a77a36b3f9cdb1, |
|||
0x0b2d2bc2d90f3e14f39ca85cd7fefa45a8e92a885c42daa99d003b969f42597d, |
|||
0x176403ebf4f777060fe4abe354ce6040fa9ecfc5786ae16cf688eb0eefba94f2, |
|||
0x2f50f3e014c57024665b5772aa6debbf7ab97d0cee8afbc398aea0c8c3d0a9d1, |
|||
0x113d1852aeee168d5fcf9e2e14145e7d2ba384f6f05e8e07bed66acd2c3bc491, |
|||
0x22376402c1dc96acbaa37c274e21b1543029b2d966b33ba918ace6f234fc384d, |
|||
0x1072c07f09517532c90fe00ea49cc84254c90f4ca2edbbcd49c8a1eb1f697902, |
|||
0x1f9333b7dea348b385995653f86f9c2e3be223912afd11bb18c800d8866ff29c, |
|||
0x2c9c33a9c2feacdba47389b4bc20c79b0b7cc26936200bf69ea5a27c4749be7f, |
|||
0x0f73f26b06c75f4fd57c980c89d171fd02e7c8119c435f49a24cc479a4833234, |
|||
0x1cb90811236a470d88b7c715fb3a74a9b6a492acdb910c873b984246fcfee4c2, |
|||
0x22dbf55d5677d6d1e0cac605667f3a6404a56fa414f9ff0dab8596af82c684dd, |
|||
0x2da8726ebf2c743deb43ad984666314494a9996600e24948d5c1177241f5cfd5, |
|||
0x2aa9d68806873b74f3973e10537494a226f5c13cc8c7958b9044e57d6d380d6f, |
|||
0x16373afa12990e5f280009e6146acc709566c771f029871a6a862f0d920b5c1c, |
|||
0x29054bafcf9f9af1d86cd6ce179538de6149cc12e87f1941f2e9d70d8ee25243, |
|||
0x234f73766998d7f080a96b9b20e8185e50eda5d93c7a20742185d8dce045fa89, |
|||
0x29e0fd2afa0655695aa558855310120c43d05c2c12b1af5680392be9d711159e, |
|||
0x24a4b6c48ce3aa487d4292414db1bbaa4edb2356217f9803882ad186c025a4ec, |
|||
0x0109813f99a5e5d3e3b3c5f20090c179b5509a1e87f5be4767ad9f2769335eed, |
|||
0x068176b175eb6d4f6be7790c7f9ceac335486fb5d2651e5ed3292c1bb52921d4, |
|||
0x2b0331e9393832024612fa348c6cb1c7e3bc0f8233b04f83dfee9c2da005b250, |
|||
0x2ca724a465a514d4ef71dca994432a392b20dd976fe4d6f3214280c285ec94a0, |
|||
0x086c36ffbc668a2207f1d8a3464376167d8b418ea5030ff496da344a458490d6, |
|||
0x1533706df2390af82e10275246db4319db1b28208c59c28a0dfc7d0635803990, |
|||
0x05f13219f8a4b1025b442d1cf526957a9a595ba140fc1d90f8c886746bc35a7b, |
|||
0x16933f8cceda41f5b4d047a1c0a2d10958563f5db08066fd9416fda4e40c68aa, |
|||
0x233096e4dceee0b3ae560189bd64c91160c350779c28f93b35d5b4a7f7712e94, |
|||
0x07fa6f6727f8e91bdf362538575a2743fec75aa8add0bd1f1a227e65fc4adcb0, |
|||
0x1c490af994c52e36d21c4d5b4a1fb657a49ccf5a810f7044a889b07b5a538d4a, |
|||
0x042a23d3d8acfbe670b16e77ba7cb966315b1ca5fd963265fe1f59eed4a2a3ec, |
|||
0x105ff3b04c267b649d03b17f609749bed73d5a2c373a1f89818033b165f48ed6, |
|||
0x1b172978ac949fdc51202f3929bf56d0ce14ab07434f4633e6f68a9559a07a7a, |
|||
0x2e575563c3bccb0e5181a47fb1ee752a7a671ecc91c17716ac56e12852ad1561, |
|||
0x2a2b0706edbd2b7eaa1f6c6a2ac566d926234c6a169615d5b7e79adb6ef93369, |
|||
0x05ace2fb7ba01279fd52d1433c42fe1fcbf27a8823fbdf788556570e3884e7c9, |
|||
0x0092f357e8f0c781bff9b90c76a4e41462fe92ea6cb36d02adb7b598ffd40046, |
|||
0x200dd359583eb7422dac26b8dc26c6ea284703005a706ea1600935dd0fc1f87b, |
|||
0x01067478a6f9a5a999e3fe87378fde5abf0d8ed56c3c1a648cee62e502e88f5b, |
|||
0x17eb93ae32e75ce3654d7f193d53c38543be71a154f43d30e67738c8abe4d659, |
|||
0x10b1f942bd7dfef88b4ef8cef12e074a3150ca31784ff3bb69cf661b01b96f87, |
|||
0x0e8b9809e17f9e7a04cb57e409eaab82a9d57302de26e5dd32666082ecb74f62, |
|||
0x042af5396847cc6ce227776d9f7481b65e0b8ce2858d2a4328c25d549b3b6fe6, |
|||
0x25fde7074f082a309bd857ff071df88b6e4004dba38650a51e117d0726785c43, |
|||
0x193eb81682f0c88ff6d3cef9dbe71962860e31b5f5dea07df62608e81f4cd331, |
|||
0x21a8ccb0264455242659b69703301b0ca924be63a5e033de8bad89a3fcfe5da9, |
|||
0x2945dd17e8a6095ab7879bb2ad6d6575c3cb92074651a1b6a452daf6d6eef668, |
|||
0x0e7bd7ddcd5b487190dfdf53bc0fb3d1efd2470210b6272ac945748aa894043c, |
|||
0x1d4f0e42124ba8ba193527db8b16283d39d77951a866b4729add8fad99ccecf8, |
|||
0x18c44546876964fb6a85492705c67d2e144128519d7a03ddd924cea47aee0dc9, |
|||
0x0d1428693bd58b2a6ceeae2745cc89a2d07bad0065228253a21564b47160acd3, |
|||
0x0246968a12a67b005dd5691d71f53d950f1ac2ce0de5835ec8883861f2761e91, |
|||
0x22127a11cecaadaadaeaeb5592f823851e5b80db5f1f4adf0f5ff013aab6acd3, |
|||
0x0bae45f539ac68829b01f9755858401af76b27d983739227478aab249c5cd08b, |
|||
0x2ffcb6c8e1671e47683a0e7d02c4170a5af758c42cea101754cf36fce6542291, |
|||
0x2673edfbf2cecc6d140e50891dd56178bb5f7daad2c7f7e82e02074174cbccbb, |
|||
0x02b132b8e30f9f07a0d51d755f652159c92e5fdd4107629912fa62c01591ab02, |
|||
0x079975637ccf42371e03c052a87310457c844122a1ebdaddb8070f44fd7730a4, |
|||
0x1beaf69915ca77b58358a696bbf84bc9ce1a478958f6ccd057c21ab826425236, |
|||
0x06e513a6c2fbb3d0160bd05263cfa95ccf6e1caef5fcc6a839a05ffe59a47fcf, |
|||
0x0d1f54c6d986976670ac11ae9fd04fe131d6690d7377b068231bed92f4c5ba0b, |
|||
0x14bbd8a734f6a043f95e69e2155cb65e4fb84cc24ac1f5c8ac6547bc303b1ef2, |
|||
0x19358e657a98d9a2244a27018a7f50758609350167ced03314211dd3fe9242d9, |
|||
0x00bca3b42d08f0f682e6e6eca315671ebf31f6cf36843cfe6073ba0f69fd8717, |
|||
0x018b4b1a387530808b953aa56733ecb3cd95a61205cb8b08aa89328b3c879757, |
|||
0x05310ae64e8e05eddce42e9370e761c965533a8685d3c2460e9e2393da1f8a37, |
|||
0x200a4c9a209660e05188ccc9e350d0ba746af52666790c365c8812d6a40ed5ea, |
|||
0x251adeccfc3943428ed6279b2ff500eaee11cf8f37910e0b57e5ade99dba36b2, |
|||
0x2df3081bd4a97303a068d662abf23fef7f33ecb67c83645e5ab3095a86925064, |
|||
0x02f7b09f7ee3d2732996fa175b5c1de3a415a5b8ad83a67323d621c8692c2c73, |
|||
0x2e2a507997465da1205a02c06ffe5013de1dbc0f5df299bf331300be45b31a1b, |
|||
0x2f99f8cb42eda5a401e00a826eec343c792bdba07965b0790487151ca065c0cc, |
|||
0x0f50f142de63f8a59e8107dc287971fe48a95bd5debcc7c5874f380c5360f6a3, |
|||
0x2172e7f369505b0ffdbac165ffbefd6b9f285206dadd6ff5c1b78aa9f6fb6809, |
|||
0x25d612d3e96dd530ed39801e24756613e5592ea44d982308cd0a9e27aab457f2, |
|||
0x2a513a7791c225df3b710369e4ffc3b332233d34044d0aad2cfe808a17025810, |
|||
0x1f765b73e2e1678499e4f3a58d317817a72a67bf318d75c51bd8175f8d4c5cbc, |
|||
0x20d3476e397dc3ce21614423e55c4f46f08fc7f9c3cb7516fecb7f2889190817, |
|||
0x17fe12fcf94ba294d2f65b0d88f500b9bcc2423cba34a68656b17c18fe38739f, |
|||
0x093d25c02dd5376c2a3902df7dd688bb4c0578f20bf5ea4f06614223d5075fe0, |
|||
0x02ad0b364a6ab3e48f3f8e8f4e9ed136b2b4acc67835340dff16d9f3b8e73f2d, |
|||
0x07b4f0e8282ee161bc085709e3c7309da10da3c6c5c879142acdb517a3fd00c5, |
|||
0x19ea14ce82444de5bd3173fe477d6819079ec48fd02c336a38ee3524d65b443e |
|||
]; |
|||
|
|||
var t; |
|||
signal t2[nrounds]; |
|||
signal t4[nrounds]; |
|||
signal t6[nrounds]; |
|||
signal t7[nrounds-1]; |
|||
|
|||
for (var i=0; i<nrounds; i++) { |
|||
t = (i==0) ? k+x_in : k + t7[i-1] + c[i]; |
|||
t2[i] <== t*t; |
|||
t4[i] <== t2[i]*t2[i]; |
|||
t6[i] <== t4[i]*t2[i]; |
|||
if (i<nrounds-1) { |
|||
t7[i] <== t6[i]*t; |
|||
} else { |
|||
out <== t6[i]*t + k; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,93 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
// --> 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<a) { |
|||
r++; |
|||
n *= 2; |
|||
} |
|||
return r; |
|||
} |
|||
*/ |
|||
|
|||
template EscalarProduct(w) { |
|||
signal input in1[w]; |
|||
signal input in2[w]; |
|||
signal output out; |
|||
signal aux[w]; |
|||
var lc = 0; |
|||
for (var i=0; i<w; i++) { |
|||
aux[i] <== in1[i]*in2[i]; |
|||
lc = lc + aux[i]; |
|||
} |
|||
out <== lc; |
|||
} |
|||
|
|||
template Decoder(w) { |
|||
signal input inp; |
|||
signal output out[w]; |
|||
signal output success; |
|||
var lc=0; |
|||
|
|||
for (var i=0; i<w; i++) { |
|||
out[i] <-- (inp == i) ? 1 : 0; |
|||
out[i] * (inp-i) === 0; |
|||
lc = lc + out[i]; |
|||
} |
|||
|
|||
lc ==> 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<wIn; j++) { |
|||
for (var k=0; k<nIn; k++) { |
|||
inp[k][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; |
|||
|
|||
|
@ -1,6 +1,6 @@ |
|||
include "../node_modules/circom/circuits/bitify.circom"; |
|||
include "../node_modules/circom/circuits/aliascheck.circom"; |
|||
include "../node_modules/circom/circuits/compconstant.circom"; |
|||
include "bitify.circom"; |
|||
include "aliascheck.circom"; |
|||
include "compconstant.circom"; |
|||
include "babyjub.circom"; |
|||
|
|||
|
@ -0,0 +1,46 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
/* 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<n; k++) { |
|||
out[k] <== a[k] * (b[k]-c[k]) + c[k]; |
|||
} |
|||
} |
@ -0,0 +1,52 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
template 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; |
|||
} |
|||
} |
@ -0,0 +1,34 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
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(); |
@ -0,0 +1,44 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
/* 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<n; k++) { |
|||
mid[k] <== b[k]*c[k]; |
|||
out[k] <== a[k] * (b[k]+c[k]-2*mid[k]) + mid[k]; |
|||
} |
|||
} |
@ -0,0 +1,27 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
template RotR(n, r) { |
|||
signal input in[n]; |
|||
signal output out[n]; |
|||
|
|||
for (var i=0; i<n; i++) { |
|||
out[i] <== in[ (i+r)%n ]; |
|||
} |
|||
} |
@ -0,0 +1,67 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
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; |
|||
} |
@ -0,0 +1,164 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
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]; |
|||
} |
|||
} |
@ -0,0 +1,32 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
template ShR(n, r) { |
|||
signal input in[n]; |
|||
signal output out[n]; |
|||
|
|||
for (var i=0; i<n; i++) { |
|||
if (i+r >= n) { |
|||
out[i] <== 0; |
|||
} else { |
|||
out[i] <== in[ i+r ]; |
|||
} |
|||
} |
|||
} |
|||
|
@ -0,0 +1,68 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
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]; |
|||
} |
|||
} |
@ -0,0 +1,45 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
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]; |
|||
} |
|||
} |
@ -0,0 +1,52 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
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]; |
|||
} |
|||
} |
@ -0,0 +1,47 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
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]; |
|||
} |
|||
} |
@ -0,0 +1,44 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
/* 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<n; k++) { |
|||
mid[k] <== b[k]*c[k]; |
|||
out[k] <== a[k] * (1 -2*b[k] -2*c[k] +4*mid[k]) + b[k] + c[k] -2*mid[k]; |
|||
} |
|||
} |
@ -1,4 +1,4 @@ |
|||
include "../node_modules/circom/circuits/compconstant.circom"; |
|||
include "compconstant.circom"; |
|||
|
|||
template Sign() { |
|||
signal input in[254]; |
@ -0,0 +1,186 @@ |
|||
/*************************************************************************************************** |
|||
|
|||
Insert to an empty leaf |
|||
======================= |
|||
|
|||
STATE OLD STATE NEW STATE |
|||
===== ========= ========= |
|||
|
|||
oldRoot newRoot |
|||
▲ ▲ |
|||
│ │ |
|||
┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ |
|||
top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐ |
|||
└───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ |
|||
│ │ |
|||
│ │ |
|||
┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ |
|||
top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│ |
|||
│ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘ |
|||
│ │ |
|||
│ │ |
|||
┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ |
|||
top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐ |
|||
└───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ |
|||
│ │ |
|||
│ │ |
|||
┌────┴────┐ ┌────┴────┐ |
|||
old0 │ 0 │ │New1Leaf │ |
|||
└─────────┘ └─────────┘ |
|||
|
|||
|
|||
┏━━━━━━━┓ ┏━━━━━━━┓ |
|||
na ┃ Hash ┃ ┃ Hash ┃ |
|||
┗━━━━━━━┛ ┗━━━━━━━┛ |
|||
|
|||
|
|||
┏━━━━━━━┓ ┏━━━━━━━┓ |
|||
na ┃ Hash ┃ ┃ Hash ┃ |
|||
┗━━━━━━━┛ ┗━━━━━━━┛ |
|||
|
|||
|
|||
|
|||
Insert to a used leaf. |
|||
===================== |
|||
|
|||
STATE OLD STATE NEW STATE |
|||
===== ========= ========= |
|||
|
|||
|
|||
oldRoot newRoot |
|||
▲ ▲ |
|||
│ │ |
|||
┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ |
|||
top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐ |
|||
└───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ |
|||
│ │ |
|||
│ │ |
|||
┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ |
|||
top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│ |
|||
│ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘ |
|||
│ │ |
|||
│ │ |
|||
┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ |
|||
top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐ |
|||
└───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ |
|||
│ │ |
|||
│ │ |
|||
┌────┴────┐ ┏━━━┻━━━┓ ┌───────┐ |
|||
old1 │Old1Leaf │ ┌─────▶┃ Hash ┃◀──┼─ 0 │ |
|||
└─────────┘ │ ┗━━━━━━━┛ └───────┘ |
|||
│ |
|||
│ |
|||
┏━━━━━━━┓ ┌───────┐ ┏━━━┻━━━┓ |
|||
bot ┃ Hash ┃ │ 0 ─┼──▶┃ Hash ┃◀─────┐ |
|||
┗━━━━━━━┛ └───────┘ ┗━━━━━━━┛ │ |
|||
│ |
|||
│ |
|||
┏━━━━━━━┓ ┏━━━┻━━━┓ ┌───────┐ |
|||
bot ┃ Hash ┃ ┌─────▶┃ Hash ┃◀──│ 0 │ |
|||
┗━━━━━━━┛ │ ┗━━━━━━━┛ └───────┘ |
|||
│ |
|||
│ |
|||
┏━━━━━━━┓ ┌─────────┐ ┏━━━┻━━━┓ ┌─────────┐ |
|||
new1 ┃ Hash ┃ │Old1Leaf ├──▶┃ Hash ┃◀──│New1Leaf │ |
|||
┗━━━━━━━┛ └─────────┘ ┗━━━━━━━┛ └─────────┘ |
|||
|
|||
|
|||
┏━━━━━━━┓ ┏━━━━━━━┓ |
|||
na ┃ Hash ┃ ┃ Hash ┃ |
|||
┗━━━━━━━┛ ┗━━━━━━━┛ |
|||
|
|||
|
|||
┏━━━━━━━┓ ┏━━━━━━━┓ |
|||
na ┃ Hash ┃ ┃ Hash ┃ |
|||
┗━━━━━━━┛ ┗━━━━━━━┛ |
|||
|
|||
***************************************************************************************************/ |
|||
|
|||
include "../node_modules/circom/circuits/gates.circom"; |
|||
include "../node_modules/circom/circuits/bitify.circom"; |
|||
|
|||
template SMTInsert(nLevels) { |
|||
signal input oldRoot; |
|||
signal input newRoot; |
|||
signal input siblings[nLevels]; |
|||
signal input oldHKey; |
|||
signal input oldHValue; |
|||
signal input newHKey; |
|||
signal input newHValue; |
|||
|
|||
component hash1Old = SMTHash1(); |
|||
hash1Old.l <== oldHKey; |
|||
hash1Old.r <== oldHValue; |
|||
|
|||
component hash1New = SMTHash1(); |
|||
hash1New.l <== newHKey; |
|||
hash1New.r <== newHValue; |
|||
|
|||
component n2bOld = Num2BinStrinct(); |
|||
component n2bNew = Num2BinStrinct(); |
|||
|
|||
component dmtLevIns = SMTLevIns(nLevels); |
|||
for (var i=0; i<nLevels; i++) dmtLevIns.siblings[i] <== siblings[i]; |
|||
|
|||
component xors[nLevels]; |
|||
for (var i=0; i<nLevels; i++) { |
|||
xors[i] = XOR(); |
|||
xors[i].a <== n2bOld.out[i]; |
|||
xors[i].a <== n2bNew.out[i]; |
|||
} |
|||
|
|||
component isOld0 = IsZero(); |
|||
isOld0.in <== oldHValue; |
|||
|
|||
component sm[nLevels]; |
|||
for (var i=0; i<sm; i++) { |
|||
sm[i] = SMTInsertSM(); |
|||
if (i==0) { |
|||
sm[i].prevst_top <== 1; |
|||
sm[i].prevst_old1 <== 0; |
|||
sm[i].prevst_old0 <== 0; |
|||
sm[i].prevst_bot <== 0; |
|||
sm[i].prevst_new1 <== 0; |
|||
sm[i].prevst_na <== 0; |
|||
} else { |
|||
sm[i].prevst_top <== sm[i-1].st_top; |
|||
sm[i].prevst_old1 <== sm[i-1].st_old1; |
|||
sm[i].prevst_old0 <== sm[i-1].st_old0; |
|||
sm[i].prevst_bot <== sm[i-1].st_bot; |
|||
sm[i].prevst_new1 <== sm[i-1].st_new1; |
|||
sm[i].prevst_na <== sm[i-1].st_na; |
|||
} |
|||
sm[i].is0 <== isOld0.out; |
|||
sm[i].xor <== xors[i].out; |
|||
sm[i].levIns <== dmtLevIns.out[i]; |
|||
} |
|||
sm[nLevels-1].prevst_na === 1; |
|||
|
|||
component levels[nLevels]; |
|||
for (var i=nLevels-1; i != -1; i--) { |
|||
levels[i] = SMTInsertLevel(); |
|||
|
|||
levels[i].st_top <== sm[i].st_top; |
|||
levels[i].st_old1 <== sm[i].st_old1; |
|||
levels[i].st_old0 <== sm[i].st_old0; |
|||
levels[i].st_bot <== sm[i].st_bot; |
|||
levels[i].st_new1 <== sm[i].st_new1; |
|||
levels[i].st_na <==sm[i].st_na; |
|||
|
|||
levels[i].sibling <== siblings[i]; |
|||
levels[i].old1leaf <== hash1Old.out; |
|||
levels[i].new1leaf <== hash1New.out; |
|||
|
|||
levels[i].new1lrbit <== n2bNew.out[i]; |
|||
if (i==nLevels-1) { |
|||
levels[i].oldChild <== 0; |
|||
levels[i].newChild <== 0; |
|||
} else { |
|||
levels[i].oldChild <== levels[i+1].oldRoot; |
|||
levels[i].newChild <== levels[i+1].newRoot; |
|||
} |
|||
} |
|||
|
|||
levels[0].oldRoot === oldRoot; |
|||
levels[0].newRoot === newRoot; |
|||
} |
@ -0,0 +1,76 @@ |
|||
|
|||
|
|||
/****** |
|||
|
|||
SMTInsertLevel |
|||
|
|||
This circuit has 2 has |
|||
|
|||
Outputs according to the state. |
|||
|
|||
State oldRoot newRoot |
|||
===== ======= ======= |
|||
top H'(oldChild, sibling) H'(newChild, sibling) |
|||
old1 old1leaf H'(newChild, 0) |
|||
old0 0 new1leaf |
|||
bot 0 H'(newChild, 0) |
|||
new1 0 H'(new1leaf, old1leaf) |
|||
na 0 0 |
|||
|
|||
H' is the Hash function with the inputs shifted acordingly. |
|||
|
|||
*****/ |
|||
|
|||
|
|||
template SMTInsertLevel() { |
|||
signal input st_top; |
|||
signal input st_old1; |
|||
signal input st_old0; |
|||
signal input st_bot; |
|||
signal input st_new1; |
|||
signal input st_na; |
|||
|
|||
signal output oldRoot; |
|||
signal output newRoot; |
|||
signal input sibling; |
|||
signal input old1leaf; |
|||
signal input new1leaf; |
|||
signal input newlrbit; |
|||
signal input oldChild; |
|||
signal input newChild; |
|||
|
|||
signal aux[4]; |
|||
|
|||
component oldProofHash = SMTHash2(); |
|||
component newProofHash = SMTHash2(); |
|||
|
|||
component oldSwitcher = Switcher(); |
|||
component newSwitcher = Switcher(); |
|||
|
|||
// Old side |
|||
|
|||
oldSwitcher.inL <== oldChild; |
|||
oldSwitcher.inR <== sibling; |
|||
|
|||
oldSwitcher.sel <== newlrbit; |
|||
oldProofHash.L <== oldSwitcher.outL; |
|||
oldProofHash.R <== oldSwitcher.outR; |
|||
|
|||
aux[0] <== old1 * st_old1; |
|||
oldRoot <== aux[0] + oldProofHash.out * st_top; |
|||
|
|||
// New side |
|||
|
|||
aux[1] <== newChild * ( st_top + st_old1 + st_but); |
|||
oldSwitcher.inL <== aux[1] + new1leaf*st_new1; |
|||
|
|||
aux[2] <== sibling*st_top; |
|||
oldSwitcher.inR <== aux[2] + old1leaf*st_new1; |
|||
|
|||
newProofHash.sel <== newlrbit; |
|||
newProofHash.L <== newProofHash.outL; |
|||
newProofHash.R <== newProofHash.outR; |
|||
|
|||
aux[3] <== newProofHash.out * (st_top + st_old1 + st_bot + st_new1); |
|||
newRoot <== aux[3] + new1leaf * st_old0; |
|||
} |
@ -0,0 +1,58 @@ |
|||
/*************************************************************************************************** |
|||
Each level on a SMTInsert has a state. |
|||
|
|||
The state of the level depends on the state of te botom level and on `xor` and |
|||
`is0` signals. |
|||
|
|||
`isOldLev` 1 when is the level where oldLeaf is. |
|||
|
|||
`xor` signal is 0 if the index bit at the current level is the same in the old |
|||
and the new index, and 1 if it is different. |
|||
|
|||
`is0` signal, is 1 if we are inserting in an empty leaf and 0 if we are inserting |
|||
in a leaf that contains an element. |
|||
|
|||
The states are: |
|||
|
|||
top: While the index bits of the old and new insex in the top level is the same, whe are in the top state. |
|||
old0 and old1: When the we reach insert level, we go to old0 and old1 states |
|||
according to `is0` signal. |
|||
btn: Once in old1 we go to btn until xor=1 |
|||
new1: This level is reached when xor=1. Here is where we insert the hash of the |
|||
old and the new trees with just one element. |
|||
na: Not appliable. After inserting it, we go to the na level. |
|||
|
|||
|
|||
|
|||
########### |
|||
levIns==curLevel # # |
|||
xor=0 is0=1 ┌────────────▶# old0 #────────┐ |
|||
┌─────┐ │ ## ## │ |
|||
│ │ │ ######### │ any |
|||
│ ▼ │ │ |
|||
│ ########### │ │ ########### |
|||
│ # # ────────────┘ └────────▶# # |
|||
└──# top # # na # |
|||
## ## ────┐ ┌──▶## ## |
|||
######### │ │ ######### |
|||
│ │ |
|||
│ ########### ########### │ any |
|||
levIns==curLevel │ # # xor=1 # # │ |
|||
is0=0 └───▶# old1 #─────────────▶# new1 #──┘ |
|||
## ## ## ## |
|||
#########──┐ ######### |
|||
│ ▲ |
|||
│ ┌─────┘ |
|||
any │ ###########│ xor=1 |
|||
│ # # |
|||
└─▶# btn # |
|||
## ## |
|||
#########◀───────┐ |
|||
│ │ |
|||
│ │ |
|||
└────────────┘ |
|||
xor=0 |
|||
|
|||
***************************************************************************************************/ |
|||
|
|||
state |
@ -0,0 +1,80 @@ |
|||
/* |
|||
|
|||
This component finds the level where the oldInsert is done. |
|||
The rules are: |
|||
|
|||
levIns[i] == 1 if its level and all the child levels have a sibling of 0 and |
|||
the parent level has a sibling != 0. Considere that the root level always has |
|||
a parent with a sibling != 0. |
|||
|
|||
|
|||
┌──────────────┐ |
|||
│ │ |
|||
│ │───▶ levIns[0] <== (1-done[i]) |
|||
│ │ |
|||
└──────────────┘ |
|||
▲ |
|||
│ |
|||
│ |
|||
done[0] |
|||
|
|||
|
|||
|
|||
done[i-1] <== levIns[i] + done[i] |
|||
▲ |
|||
│ |
|||
│ |
|||
┌───────────┐ ┌──────────────┐ |
|||
│ │ │ │ |
|||
sibling[i-1]───▶│IsZero[i-1]│─▶│ │───▶ levIns[i] <== (1-done[i])*(1-isZero[i-1].out) |
|||
│ │ │ │ |
|||
└───────────┘ └──────────────┘ |
|||
▲ |
|||
│ |
|||
│ |
|||
done[i] |
|||
|
|||
|
|||
|
|||
done[n-2] <== levIns[n-1] |
|||
▲ |
|||
│ |
|||
│ |
|||
┌───────────┐ ┌──────────────┐ |
|||
│ │ │ │ |
|||
sibling[n-2]───▶│IsZero[n-2]│─▶│ │────▶ levIns[n-1] <== (1-isZero[n-2].out) |
|||
│ │ │ │ |
|||
└───────────┘ └──────────────┘ |
|||
|
|||
┌───────────┐ |
|||
│ │ |
|||
sibling[n-1]───▶│IsZero[n-1]│────▶ === 0 |
|||
│ │ |
|||
└───────────┘ |
|||
|
|||
*/ |
|||
|
|||
template SMTLevIns(nLevels) { |
|||
signal input siblins[nLevels]; |
|||
signal output levIns[nLevels]; |
|||
signal done[nLevels-1]; // Indicates if the insLevel has aready been detecetd. |
|||
|
|||
component isZero[nLevels]; |
|||
|
|||
for (var i=0; i<nLevels; i++) { |
|||
isZero[i] = IsZero(); |
|||
isZero[i].in <== siblings[i]; |
|||
} |
|||
|
|||
// The last level must always have a sibling of 0. If not, then it cannot be inserted. |
|||
isZero[nLevels-2].out === 1; |
|||
|
|||
levIns[nLevels-1] <== (1-isZero[nLevels-2].out); |
|||
done[nLevels-2] <== levIns[nLevels-1]; |
|||
for (var i=nLevels-2; i>0; i--) { |
|||
levIns[i] <== (1-done[i])*(1-isZero[i-1].out) |
|||
done[i-1] <== levIns[i] + done[i]; |
|||
} |
|||
|
|||
levIns[0] <== (1-done[0]); |
|||
} |
@ -0,0 +1,189 @@ |
|||
// Copyright (c) 2018 Jordi Baylina
|
|||
// License: LGPL-3.0+
|
|||
//
|
|||
|
|||
|
|||
const Web3 = require("web3"); |
|||
const assert = require("assert"); |
|||
|
|||
class Contract { |
|||
constructor() { |
|||
this.code = []; |
|||
this.labels = {}; |
|||
this.pendingLabels = {}; |
|||
} |
|||
|
|||
createTxData() { |
|||
let C; |
|||
|
|||
// Check all labels are defined
|
|||
const pendingLabels = Object.keys(this.pendingLabels); |
|||
if (pendingLabels.length>0) { |
|||
throw new Error("Lables not defined: "+ pendingLabels.join(", ")); |
|||
} |
|||
|
|||
let setLoaderLength = 0; |
|||
let genLoadedLength = -1; |
|||
|
|||
while (genLoadedLength!=setLoaderLength) { |
|||
setLoaderLength = genLoadedLength; |
|||
C = new module.exports(); |
|||
C.codesize(); |
|||
C.push(setLoaderLength); |
|||
C.push(0); |
|||
C.codecopy(); |
|||
|
|||
C.push(this.code.length); |
|||
C.push(0); |
|||
C.return(); |
|||
genLoadedLength = C.code.length; |
|||
} |
|||
|
|||
return Web3.utils.bytesToHex(C.code.concat(this.code)); |
|||
} |
|||
|
|||
stop() { this.code.push(0x00); } |
|||
add() { this.code.push(0x01); } |
|||
mul() { this.code.push(0x02); } |
|||
sub() { this.code.push(0x03); } |
|||
div() { this.code.push(0x04); } |
|||
sdiv() { this.code.push(0x05); } |
|||
mod() { this.code.push(0x06); } |
|||
smod() { this.code.push(0x07); } |
|||
addmod() { this.code.push(0x08); } |
|||
mulmod() { this.code.push(0x09); } |
|||
exp() { this.code.push(0x0a); } |
|||
signextend() { this.code.push(0x0b); } |
|||
|
|||
lt() { this.code.push(0x10); } |
|||
gt() { this.code.push(0x11); } |
|||
slt() { this.code.push(0x12); } |
|||
sgt() { this.code.push(0x13); } |
|||
eq() { this.code.push(0x14); } |
|||
iszero() { this.code.push(0x15); } |
|||
and() { this.code.push(0x16); } |
|||
or() { this.code.push(0x17); } |
|||
shor() { this.code.push(0x18); } |
|||
not() { this.code.push(0x19); } |
|||
byte() { this.code.push(0x1a); } |
|||
|
|||
keccak() { this.code.push(0x20); } |
|||
sha3() { this.code.push(0x20); } // alias
|
|||
|
|||
address() { this.code.push(0x30); } |
|||
balance() { this.code.push(0x31); } |
|||
origin() { this.code.push(0x32); } |
|||
caller() { this.code.push(0x33); } |
|||
callvalue() { this.code.push(0x34); } |
|||
calldataload() { this.code.push(0x35); } |
|||
calldatasize() { this.code.push(0x36); } |
|||
calldatacopy() { this.code.push(0x37); } |
|||
codesize() { this.code.push(0x38); } |
|||
codecopy() { this.code.push(0x39); } |
|||
gasprice() { this.code.push(0x3a); } |
|||
extcodesize() { this.code.push(0x3b); } |
|||
extcodecopy() { this.code.push(0x3c); } |
|||
returndatasize() { this.code.push(0x3d); } |
|||
returndatacopy() { this.code.push(0x3e); } |
|||
|
|||
blockhash() { this.code.push(0x40); } |
|||
coinbase() { this.code.push(0x41); } |
|||
timestamp() { this.code.push(0x42); } |
|||
number() { this.code.push(0x43); } |
|||
difficulty() { this.code.push(0x44); } |
|||
gaslimit() { this.code.push(0x45); } |
|||
|
|||
pop() { this.code.push(0x50); } |
|||
mload() { this.code.push(0x51); } |
|||
mstore() { this.code.push(0x52); } |
|||
mstore8() { this.code.push(0x53); } |
|||
sload() { this.code.push(0x54); } |
|||
sstore() { this.code.push(0x55); } |
|||
|
|||
_pushLabel(label) { |
|||
if (typeof this.labels[label] != "undefined") { |
|||
this.push(this.labels[label]); |
|||
} else { |
|||
this.pendingLabels[label] = this.pendingLabels[label] || []; |
|||
this.pendingLabels[label].push(this.code.length); |
|||
this.push("0x000000"); |
|||
} |
|||
} |
|||
|
|||
_fillLabel(label) { |
|||
if (!this.pendingLabels[label]) return; |
|||
|
|||
let dst = this.labels[label]; |
|||
|
|||
const dst3 = [dst >> 16, (dst >> 8) & 0xFF, dst & 0xFF]; |
|||
|
|||
this.pendingLabels[label].forEach((p) => { |
|||
for (let i=0; i<3; i++) { |
|||
this.code[p+i+1] = dst3[i]; |
|||
} |
|||
}); |
|||
|
|||
delete this.pendingLabels[label]; |
|||
} |
|||
|
|||
|
|||
jmp(label) { |
|||
this._pushLabel(label); |
|||
this.code.push(0x56); |
|||
} |
|||
|
|||
jmpi(label) { |
|||
this._pushLabel(label); |
|||
this.code.push(0x57); |
|||
} |
|||
|
|||
pc() { this.code.push(0x58); } |
|||
msize() { this.code.push(0x59); } |
|||
gas() { this.code.push(0x5a); } |
|||
label(name) { |
|||
assert(typeof this.labels[name] == "undefined", "Label already defined"); |
|||
this.labels[name] = this.code.length; |
|||
this.code.push(0x5b); |
|||
|
|||
this._fillLabel(name); |
|||
} |
|||
|
|||
push(data) { |
|||
const d = Web3.utils.hexToBytes(Web3.utils.toHex(data)); |
|||
assert(d.length>0); |
|||
assert(d.length<=32); |
|||
this.code = this.code.concat([0x5F + d.length], d); |
|||
} |
|||
|
|||
dup(n) { |
|||
assert(n>=0); |
|||
assert(n<16); |
|||
this.code.push(0x80 + n); |
|||
} |
|||
|
|||
swap(n) { |
|||
assert(n>=1); |
|||
assert(n<=16); |
|||
this.code.push(0x8f + n); |
|||
} |
|||
|
|||
log0() { this.code.push(0xa0); } |
|||
log1() { this.code.push(0xa1); } |
|||
log2() { this.code.push(0xa2); } |
|||
log3() { this.code.push(0xa3); } |
|||
log4() { this.code.push(0xa4); } |
|||
|
|||
create() { this.code.push(0xf0); } |
|||
call() { this.code.push(0xf1); } |
|||
callcode() { this.code.push(0xf2); } |
|||
return() { this.code.push(0xf3); } |
|||
delegatecall() { this.code.push(0xf4); } |
|||
|
|||
staticcall() { this.code.push(0xfa); } |
|||
revert() { this.code.push(0xfd); } |
|||
invalid() { this.code.push(0xfe); } |
|||
selfdestruct() { this.code.push(0xff); } |
|||
} |
|||
|
|||
module.exports = Contract; |
|||
|
@ -0,0 +1,37 @@ |
|||
const bn128 = require("snarkjs").bn128; |
|||
const bigInt = require("snarkjs").bigInt; |
|||
const Web3 = require("web3"); |
|||
const F = bn128.Fr; |
|||
|
|||
module.exports.hash = MiMC7Hash; |
|||
module.exports.getConstants = getConstants; |
|||
|
|||
const SEED = "iden3_mimc"; |
|||
|
|||
function getConstants(seed, nRounds) { |
|||
const cts = new Array(nRounds); |
|||
let c = Web3.utils.keccak256(SEED); |
|||
for (let i=1; i<nRounds; i++) { |
|||
c = Web3.utils.keccak256(c); |
|||
|
|||
const n1 = Web3.utils.toBN(c).mod(Web3.utils.toBN(F.q.toString())); |
|||
cts[i] = Web3.utils.padLeft(Web3.utils.toHex(n1), 64); |
|||
} |
|||
cts[0] = "0x0000000000000000000000000000000000000000000000000000000000000000"; |
|||
return cts; |
|||
} |
|||
|
|||
function MiMC7Hash(_x_in, _k, nRounds) { |
|||
const x_in = bigInt(_x_in); |
|||
const k = bigInt(_k); |
|||
const cts = getConstants(SEED, nRounds); |
|||
let r; |
|||
for (let i=0; i<nRounds; i++) { |
|||
const c = bigInt(Web3.utils.toBN(cts[i]).toString()); |
|||
let t = (i==0) ? F.add(x_in, k) : F.add(F.add(r, k), c); |
|||
let t2 = F.square(t); |
|||
let t4 = F.square(t2); |
|||
r = F.mul(F.mul(t4, t2), t); |
|||
} |
|||
return F.affine(F.add(r, k)); |
|||
} |
@ -0,0 +1,114 @@ |
|||
// Copyright (c) 2018 Jordi Baylina
|
|||
// License: LGPL-3.0+
|
|||
//
|
|||
|
|||
const Web3 = require("web3"); |
|||
|
|||
const Contract = require("./evmasm"); |
|||
|
|||
function createCode(seed, n) { |
|||
|
|||
let ci = Web3.utils.keccak256(seed); |
|||
|
|||
const C = new Contract(); |
|||
|
|||
C.push(0x44); |
|||
C.push("0x00"); |
|||
C.push("0x00"); |
|||
C.calldatacopy(); |
|||
C.push("0x0100000000000000000000000000000000000000000000000000000000"); |
|||
C.push("0x00"); |
|||
C.mload(); |
|||
C.div(); |
|||
C.push("0xd15ca109"); // MiMCpe7(uint256,uint256)
|
|||
// C.push("0x8c42199e"); // MiMCpe7(uint256,uint256,uint256)
|
|||
C.eq(); |
|||
C.jmpi("start"); |
|||
C.invalid(); |
|||
|
|||
C.label("start"); |
|||
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
|||
C.push("0x24"); |
|||
C.mload(); // k q
|
|||
|
|||
|
|||
C.dup(1); // q k q
|
|||
C.dup(0); // q q k q
|
|||
C.push("0x04"); |
|||
C.mload(); // x q q k q
|
|||
C.dup(3); // k x q q k q
|
|||
C.addmod(); // t=x+k q k q
|
|||
C.dup(1); // q t q k q
|
|||
C.dup(0); // q q t q k q
|
|||
C.dup(2); // t q q t q k q
|
|||
C.dup(0); // t t q q t q k q
|
|||
C.mulmod(); // a=t^2 q t q k q
|
|||
C.dup(1); // q a q t q k q
|
|||
C.dup(1); // a q a q t q k q
|
|||
C.dup(0); // a a q a q t q k q
|
|||
C.mulmod(); // b=t^4 a q t q k q
|
|||
C.mulmod(); // c=t^6 t q k q
|
|||
C.mulmod(); // r=t^7 k q
|
|||
|
|||
for (let i=0; i<n-1; i++) { |
|||
ci = Web3.utils.keccak256(ci); |
|||
C.dup(2); // q r k q
|
|||
C.dup(0); // q q r k q
|
|||
C.dup(0); // q q q r k q
|
|||
C.swap(3); // r q q q k q
|
|||
C.push(ci); // c r q q k q
|
|||
C.addmod(); // s=c+r q q k q
|
|||
C.dup(3); // k s q q k q
|
|||
C.addmod(); // t=s+k q k q
|
|||
C.dup(1); // q t q k q
|
|||
C.dup(0); // q q t q k q
|
|||
C.dup(2); // t q q t q k q
|
|||
C.dup(0); // t t q q t q k q
|
|||
C.mulmod(); // a=t^2 q t q k q
|
|||
C.dup(1); // q a q t q k q
|
|||
C.dup(1); // a q a q t q k q
|
|||
C.dup(0); // a a q a q t q k q
|
|||
C.mulmod(); // b=t^4 a q t q k q
|
|||
C.mulmod(); // c=t^6 t q k q
|
|||
C.mulmod(); // r=t^7 k q
|
|||
} |
|||
|
|||
C.addmod(); // res=t^7+k
|
|||
C.push("0x00"); |
|||
C.mstore(); // Save it to pos 0;
|
|||
C.push("0x20"); |
|||
C.push("0x00"); |
|||
C.return(); |
|||
|
|||
return C.createTxData(); |
|||
} |
|||
|
|||
module.exports.abi = [ |
|||
{ |
|||
"constant": true, |
|||
"inputs": [ |
|||
{ |
|||
"name": "in_x", |
|||
"type": "uint256" |
|||
}, |
|||
{ |
|||
"name": "in_k", |
|||
"type": "uint256" |
|||
} |
|||
], |
|||
"name": "MiMCpe7", |
|||
"outputs": [ |
|||
{ |
|||
"name": "out_x", |
|||
"type": "uint256" |
|||
} |
|||
], |
|||
"payable": false, |
|||
"stateMutability": "pure", |
|||
"type": "function" |
|||
} |
|||
]; |
|||
|
|||
module.exports.createCode = createCode; |
|||
|
|||
|
@ -0,0 +1,18 @@ |
|||
const mimc = require("./mimc7"); |
|||
|
|||
const SEED = "iden3_mimc"; |
|||
|
|||
let nRounds; |
|||
if (typeof process.argv[2] != "undefined") { |
|||
nRounds = parseInt(process.argv[2]); |
|||
} else { |
|||
nRounds = 256; |
|||
} |
|||
|
|||
const cts = mimc.getConstants(SEED, nRounds); |
|||
|
|||
for (let i=0; i<nRounds; i++) { |
|||
let S = cts[i]; |
|||
if (i<nRounds-1) S=S+","; |
|||
console.log(S); |
|||
} |
@ -0,0 +1,12 @@ |
|||
const mimcGenContract = require("./mimc_gencontract"); |
|||
|
|||
const SEED = "iden3_mimc"; |
|||
|
|||
let nRounds; |
|||
if (typeof process.argv[2] != "undefined") { |
|||
nRounds = parseInt(process.argv[2]); |
|||
} else { |
|||
nRounds = 91; |
|||
} |
|||
|
|||
console.log(mimcGenContract.createCode(SEED, nRounds)); |
@ -1,10 +0,0 @@ |
|||
const snarkjs = require("snarkjs"); |
|||
|
|||
let n = 16352677002768649294638363183714474939219394808856154771098596513875516795430n |
|||
|
|||
let r = snarkjs.bn128.Fr.sqrt(n) |
|||
|
|||
r = snarkjs.bn128.Fr.q -r; |
|||
|
|||
console.log(r.toString()); |
|||
|
@ -1,3 +1,3 @@ |
|||
include "../../node_modules/circom/circuits/aliascheck.circom"; |
|||
include "../../circuits/aliascheck.circom"; |
|||
|
|||
component main = AliasCheck() |
@ -1,3 +1,3 @@ |
|||
include "../../circuit/babyjub.circom"; |
|||
include "../../circuits/babyjub.circom"; |
|||
|
|||
component main = BabyAdd(); |
@ -1,3 +1,3 @@ |
|||
include "../../circuit/babyjub.circom"; |
|||
include "../../circuits/babyjub.circom"; |
|||
|
|||
component main = BabyCheck(); |
@ -0,0 +1,18 @@ |
|||
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(); |
@ -1,3 +1,3 @@ |
|||
include "../../circuit/eddsa.circom"; |
|||
include "../../circuits/eddsa.circom"; |
|||
|
|||
component main = EdDSAVerifier(80); |
@ -1,3 +1,3 @@ |
|||
include "../../circuit/montgomery.circom"; |
|||
include "../../circuits/montgomery.circom"; |
|||
|
|||
component main = Edwards2Montgomery(); |
@ -0,0 +1,4 @@ |
|||
|
|||
include "../../circuits/comparators.circom"; |
|||
|
|||
component main = IsEqual(); |
@ -0,0 +1,5 @@ |
|||
|
|||
|
|||
include "../../circuits/comparators.circom"; |
|||
|
|||
component main = IsZero(); |
@ -0,0 +1,4 @@ |
|||
|
|||
include "../../circuits/comparators.circom"; |
|||
|
|||
component main = LessThan(32); |
@ -0,0 +1,3 @@ |
|||
include "../../circuits/mimc.circom" |
|||
|
|||
component main = MiMC7(91); |
@ -1,3 +1,3 @@ |
|||
include "../../circuit/montgomery.circom"; |
|||
include "../../circuits/montgomery.circom"; |
|||
|
|||
component main = Montgomery2Edwards(); |
@ -1,3 +1,3 @@ |
|||
include "../../circuit/montgomery.circom"; |
|||
include "../../circuits/montgomery.circom"; |
|||
|
|||
component main = MontgomeryAdd(); |
@ -1,3 +1,3 @@ |
|||
include "../../circuit/montgomery.circom"; |
|||
include "../../circuits/montgomery.circom"; |
|||
|
|||
component main = MontgomeryDouble(); |
@ -0,0 +1,15 @@ |
|||
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(); |
@ -1,3 +1,3 @@ |
|||
include "../../circuit/sign.circom"; |
|||
include "../../circuits/sign.circom"; |
|||
|
|||
component main = Sign(); |
@ -0,0 +1,26 @@ |
|||
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(); |
@ -0,0 +1,77 @@ |
|||
const chai = require("chai"); |
|||
const path = require("path"); |
|||
const snarkjs = require("snarkjs"); |
|||
const crypto = require("crypto"); |
|||
|
|||
const compiler = require("circom"); |
|||
|
|||
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))); |
|||
}); |
|||
}); |
@ -0,0 +1,22 @@ |
|||
|
|||
const snarkjs = require("snarkjs"); |
|||
|
|||
const bigInt = snarkjs.bigInt; |
|||
|
|||
module.exports = function hexBits(cir, witness, sig, nBits) { |
|||
let v = bigInt(0); |
|||
for (let i=nBits-1; i>=0; i--) { |
|||
v = v.shiftLeft(1); |
|||
const name = sig+"["+i+"]"; |
|||
const idx = cir.getSignalIdx(name); |
|||
const vbit = bigInt(witness[idx].toString()); |
|||
if (vbit.equals(bigInt(1))) { |
|||
v = v.add(bigInt(1)); |
|||
} else if (vbit.equals(bigInt(0))) { |
|||
v; |
|||
} else { |
|||
console.log("Not Binary: "+name); |
|||
} |
|||
} |
|||
return v.toString(16); |
|||
}; |
@ -0,0 +1,178 @@ |
|||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ |
|||
/* 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<N; i++) { |
|||
M[i] = new Array(16); |
|||
for (let j=0; j<16; j++) { // encode 4 chars per integer (64 per block), big-endian encoding
|
|||
M[i][j] = (msg.charCodeAt(i*64+j*4+0)<<24) | (msg.charCodeAt(i*64+j*4+1)<<16) |
|||
| (msg.charCodeAt(i*64+j*4+2)<< 8) | (msg.charCodeAt(i*64+j*4+3)<< 0); |
|||
} // note running off the end of msg is ok 'cos bitwise ops on NaN return 0
|
|||
} |
|||
// add length (in bits) into final pair of 32-bit integers (big-endian) [§5.1.1]
|
|||
// note: most significant word would be (len-1)*8 >>> 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<N; i++) { |
|||
const W = new Array(64); |
|||
|
|||
// 1 - prepare message schedule 'W'
|
|||
for (let t=0; t<16; t++) W[t] = M[i][t]; |
|||
for (let t=16; t<64; t++) { |
|||
W[t] = (Sha256.σ1(W[t-2]) + W[t-7] + Sha256.σ0(W[t-15]) + W[t-16]) >>> 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<H.length; h++) H[h] = ('00000000'+H[h].toString(16)).slice(-8); |
|||
|
|||
// concatenate H0..H7, with separator if required
|
|||
const separator = opt.outFormat=='hex-w' ? ' ' : ''; |
|||
|
|||
return H.join(separator); |
|||
|
|||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ |
|||
|
|||
function utf8Encode(str) { |
|||
try { |
|||
return new TextEncoder().encode(str, 'utf-8').reduce((prev, curr) => 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
|
|||
|
@ -0,0 +1,35 @@ |
|||
const chai = require("chai"); |
|||
const path = require("path"); |
|||
const snarkjs = require("snarkjs"); |
|||
const compiler = require("circom"); |
|||
|
|||
const mimcjs = require("../src/mimc7.js"); |
|||
|
|||
const assert = chai.assert; |
|||
|
|||
describe("MiMC Circuit test", function () { |
|||
let circuit; |
|||
|
|||
this.timeout(100000); |
|||
|
|||
before( async () => { |
|||
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_test.circom")); |
|||
|
|||
circuit = new snarkjs.Circuit(cirDef); |
|||
|
|||
console.log("MiMC constraints: " + circuit.nConstraints); |
|||
}); |
|||
|
|||
it("Should check constrain", async () => { |
|||
const w = circuit.calculateWitness({x_in: 1, k: 2}); |
|||
|
|||
const res = w[circuit.getSignalIdx("main.out")]; |
|||
|
|||
const res2 = mimcjs.hash(1,2,91); |
|||
|
|||
assert.equal(res.toString(), res2.toString()); |
|||
|
|||
assert(circuit.checkWitness(w)); |
|||
|
|||
}); |
|||
}); |
@ -0,0 +1,52 @@ |
|||
const TestRPC = require("ganache-cli"); |
|||
const Web3 = require("web3"); |
|||
const chai = require("chai"); |
|||
const mimcGenContract = require("../src/mimc_gencontract.js"); |
|||
const mimcjs = require("../src/mimc7.js"); |
|||
|
|||
|
|||
const assert = chai.assert; |
|||
const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); }; |
|||
|
|||
const SEED = "iden3_mimc"; |
|||
|
|||
describe("MiMC Smart contract test", () => { |
|||
let testrpc; |
|||
let web3; |
|||
let mimc; |
|||
let accounts; |
|||
|
|||
before(async () => { |
|||
testrpc = TestRPC.server({ |
|||
ws: true, |
|||
gasLimit: 5800000, |
|||
total_accounts: 10, |
|||
}); |
|||
|
|||
testrpc.listen(8546, "127.0.0.1"); |
|||
|
|||
web3 = new Web3("ws://127.0.0.1:8546"); |
|||
accounts = await web3.eth.getAccounts(); |
|||
}); |
|||
|
|||
after(async () => testrpc.close()); |
|||
|
|||
it("Should deploy the contract", async () => { |
|||
const C = new web3.eth.Contract(mimcGenContract.abi); |
|||
|
|||
mimc = await C.deploy({ |
|||
data: mimcGenContract.createCode(SEED, 91) |
|||
}).send({ |
|||
gas: 1500000, |
|||
from: accounts[0] |
|||
}); |
|||
}); |
|||
|
|||
it("Shold calculate the mimic correctly", async () => { |
|||
const res = await mimc.methods.MiMCpe7(1,2).call(); |
|||
const res2 = await mimcjs.hash(1,2,91); |
|||
|
|||
assert.equal(res.toString(), res2.toString()); |
|||
}); |
|||
}); |
|||
|
@ -0,0 +1,42 @@ |
|||
const chai = require("chai"); |
|||
const path = require("path"); |
|||
const snarkjs = require("snarkjs"); |
|||
const crypto = require("crypto"); |
|||
|
|||
const compiler = require("circom"); |
|||
|
|||
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); |
|||
|
|||
|
|||
}); |
@ -0,0 +1,35 @@ |
|||
const chai = require("chai"); |
|||
const path = require("path"); |
|||
const snarkjs = require("snarkjs"); |
|||
const crypto = require("crypto"); |
|||
|
|||
const compiler = require("circom"); |
|||
|
|||
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"))); |
|||
}); |
|||
}); |