├── .gitignore ├── .gitmodules ├── README.md ├── build └── contracts │ ├── IMimc.json │ ├── MerkelTree.json │ ├── Migrations.json │ ├── Mixer.json │ ├── Pairing.json │ └── Verifier.json ├── circomlib ├── .eslintrc.js ├── .gitignore ├── README.md ├── calcpedersenbases │ └── calcpedersenbases.js ├── circuits │ ├── README.md │ ├── aliascheck.circom │ ├── babyjub.circom │ ├── binsub.circom │ ├── binsum.circom │ ├── bitify.circom │ ├── comparators.circom │ ├── compconstant.circom │ ├── eddsa.circom │ ├── eddsamimc.circom │ ├── eddsamimcsponge.circom │ ├── eddsaposeidon.circom │ ├── escalarmul.circom │ ├── escalarmulany.circom │ ├── escalarmulfix.circom │ ├── escalarmulw4table.circom │ ├── gates.circom │ ├── mimc.circom │ ├── mimcsponge.circom │ ├── montgomery.circom │ ├── multiplexer.circom │ ├── mux1.circom │ ├── mux2.circom │ ├── mux3.circom │ ├── mux4.circom │ ├── pedersen.circom │ ├── pedersen_old.circom │ ├── pointbits.circom │ ├── poseidon.circom │ ├── sha256 │ │ ├── ch.circom │ │ ├── constants.circom │ │ ├── main.circom │ │ ├── maj.circom │ │ ├── rotate.circom │ │ ├── sha256.circom │ │ ├── sha256_2.circom │ │ ├── sha256compression.circom │ │ ├── shift.circom │ │ ├── sigma.circom │ │ ├── sigmaplus.circom │ │ ├── t1.circom │ │ ├── t2.circom │ │ └── xor3.circom │ ├── sign.circom │ ├── smt │ │ ├── smthash_mimc.circom │ │ ├── smthash_poseidon.circom │ │ ├── smtlevins.circom │ │ ├── smtprocessor.circom │ │ ├── smtprocessorlevel.circom │ │ ├── smtprocessorsm.circom │ │ ├── smtverifier.circom │ │ ├── smtverifierlevel.circom │ │ └── smtverifiersm.circom │ └── switcher.circom ├── doc │ ├── root_transfer.monopic │ ├── smt_diagram_0.monopic │ ├── smt_diagram_1.monopic │ ├── smt_hash.monopic │ ├── smt_levins.monopic │ ├── smt_sm.monopic │ ├── smt_verifier_sm.monopic │ ├── voting.monopic │ ├── window.monopic │ └── window_chain.monopic ├── index.js ├── package-lock.json ├── package.json ├── src │ ├── babyjub.js │ ├── eddsa.js │ ├── evmasm.js │ ├── g2_gencontract.js │ ├── mimc7.js │ ├── mimc_gencontract.js │ ├── mimc_print_iv.js │ ├── mimc_printconstants.js │ ├── mimc_printcontract.js │ ├── mimcsponge.js │ ├── mimcsponge_gencontract.js │ ├── mimcsponge_printconstants.js │ ├── mimcsponge_printcontract.js │ ├── pedersenHash.js │ ├── pedersen_printbases.js │ ├── poseidon.js │ ├── poseidon_gencontract.js │ ├── poseidon_printconstants.js │ ├── poseidon_printcontract.js │ ├── poseidon_printmatrix.js │ ├── smt.js │ ├── smt_hashes_mimc.js │ ├── smt_hashes_poseidon.js │ └── smt_memdb.js └── test │ ├── aliascheck.js │ ├── babyjub.js │ ├── babyjub_js.js │ ├── binsub.js │ ├── binsum.js │ ├── circuits │ ├── aliascheck_test.circom │ ├── babyadd_tester.circom │ ├── babycheck_test.circom │ ├── babypbk_test.circom │ ├── binsub_test.circom │ ├── constants_test.circom │ ├── eddsa_test.circom │ ├── eddsamimc_test.circom │ ├── eddsaposeidon_test.circom │ ├── edwards2montgomery.circom │ ├── escalarmul_min_test.circom │ ├── escalarmul_test.circom │ ├── escalarmul_test_min.circom │ ├── escalarmulany_test.circom │ ├── escalarmulfix_test.circom │ ├── escalarmulw4table.circom │ ├── escalarmulw4table_test.circom │ ├── escalarmulw4table_test3.circom │ ├── greatereqthan.circom │ ├── greaterthan.circom │ ├── isequal.circom │ ├── iszero.circom │ ├── lesseqthan.circom │ ├── lessthan.circom │ ├── mimc_sponge_hash_test.circom │ ├── mimc_sponge_test.circom │ ├── mimc_test.circom │ ├── montgomery2edwards.circom │ ├── montgomeryadd.circom │ ├── montgomerydouble.circom │ ├── mux1_1.circom │ ├── mux2_1.circom │ ├── mux3_1.circom │ ├── mux4_1.circom │ ├── pedersen2_test.circom │ ├── pedersen_test.circom │ ├── pointbits_loopback.circom │ ├── poseidon_test.circom │ ├── sha256_2_test.circom │ ├── sha256_test448.circom │ ├── sha256_test512.circom │ ├── sign_test.circom │ ├── smtprocessor10_test.circom │ ├── smtverifier10_test.circom │ └── sum_test.circom │ ├── comparators.js │ ├── eddsa.js │ ├── eddsa_js.js │ ├── eddsamimc.js │ ├── eddsaposeidon.js │ ├── escalarmul.js │ ├── escalarmulany.js │ ├── escalarmulfix.js │ ├── helpers │ ├── printsignal.js │ └── sha256.js │ ├── mimccircuit.js │ ├── mimccontract.js │ ├── mimcspongecircuit.js │ ├── mimcspongecontract.js │ ├── montgomery.js │ ├── multiplexer.js │ ├── pedersen.js │ ├── pedersen2.js │ ├── point2bits.js │ ├── poseidoncircuit.js │ ├── poseidoncontract.js │ ├── rawsmt3.circom │ ├── sha256.js │ ├── sign.js │ ├── smtjs.js │ ├── smtprocessor.js │ ├── smtverifier.js │ └── smtverifier_adria.js ├── circuit ├── MiMCMerkle.js ├── circuit.json ├── generate_leaf_existence_input.js ├── get_merkle_root.circom ├── input.json ├── mixer.circom ├── proof.json ├── proving_key.json ├── public.json ├── test.js ├── verification_key.json ├── verifier.sol └── witness.json ├── contracts ├── MerkleTree.sol ├── Migrations.sol ├── Mixer.sol └── verifier.sol ├── deploy ├── call_mimc.js ├── call_mixer.js ├── deploy_mimc.js └── gen_contract.js ├── migrations ├── 1_initial_migration.js └── 2_deploy_contracts.js ├── package-lock.json ├── package.json └── truffle.js /.gitignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | node_modules/ 3 | scripts/ 4 | circomlib/node_modules -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "circomlib"] 2 | path = circomlib 3 | url = https://github.com/iden3/circomlib 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 准备 2 | 3 | - circom 版本 4 | - 0.0.19 5 | - python 版本 6 | - 2.7.16 7 | - nodejs 版本 8 | - v10.16.0 9 | - solidity 版本 10 | - 0.5.0 11 | 12 | 使用的hash函数为:mimc7 13 | 14 | ### 开发步骤 15 | 16 | - 编写电路 17 | - mixer 18 | - get_merkle_root.circom 19 | 20 | - 编写合约 21 | - mixer 22 | - Merkle 23 | 24 | ### 电路 25 | 26 | #### 编译电路 27 | 28 | 编译电路,并将编译好的电路以json格式输出 29 | 30 | ``` 31 | $ circom .circom -o circuit.json 32 | ``` 33 | 34 | #### 生成电路的输入 35 | 36 | 为电路生成public input,Private input 37 | 38 | ``` 39 | $ node generate_circuit_input.js 40 | ``` 41 | 42 | #### 计算 witness 43 | 44 | 使用编译好的电路及input生成witness 45 | 46 | ``` 47 | $ snarkjs calculatewitness -c circuit.json -i input.json 48 | ``` 49 | 50 | #### trust setup 51 | 52 | ``` 53 | $ snarkjs setup -c circuit.json --protocol groth 54 | ``` 55 | 56 | #### 生成证明 57 | 58 | ``` 59 | $ snarkjs proof -w witness.json --pk proving_key.json 60 | ``` 61 | 62 | #### 校验证明 63 | 64 | ``` 65 | $ snarkjs verify 66 | ``` 67 | 68 | #### 生成solidity verifier 69 | 70 | ``` 71 | $ snarkjs generateverifier 72 | 73 | ``` 74 | 75 | #### 生成solidity 调用参数 76 | 77 | ``` 78 | $ snarkjs generatecall 79 | ``` 80 | 81 | [文档地址](https://keen-noyce-c29dfa.netlify.com/#2) 82 | 83 | mixer 合约: 0x46a7f914785357b9054fdB670845DC6c0c968167 -------------------------------------------------------------------------------- /circomlib/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "plugins": [ 3 | "mocha" 4 | ], 5 | "env": { 6 | "es6": true, 7 | "node": true, 8 | "mocha": true 9 | }, 10 | "parserOptions": { 11 | "ecmaVersion": 2017 12 | }, 13 | "extends": "eslint:recommended", 14 | "rules": { 15 | "indent": [ 16 | "error", 17 | 4 18 | ], 19 | "linebreak-style": [ 20 | "error", 21 | "unix" 22 | ], 23 | "quotes": [ 24 | "error", 25 | "double" 26 | ], 27 | "semi": [ 28 | "error", 29 | "always" 30 | ], 31 | "mocha/no-exclusive-tests": "error" 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /circomlib/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | tmp 64 | 65 | .DS_Store -------------------------------------------------------------------------------- /circomlib/README.md: -------------------------------------------------------------------------------- 1 | # CircomLib 2 | 3 | ## Description 4 | 5 | - This repository contains a library of circuit templates. 6 | - All files are copyrighted under 2018 0KIMS association and part of the free software [circom](https://github.com/iden3/circom) (Zero Knowledge Circuit Compiler). 7 | 8 | ## Organisation 9 | 10 | This respository contains 5 folders: 11 | - `circuits`: it contains the implementation of different cryptographic primitives in circom language. 12 | - `calcpedersenbases`: set of functions in JavaScript used to find a set of points in [Baby Jubjub](https://github.com/barryWhiteHat/baby_jubjub) elliptic curve that serve as basis for the [Pedersen Hash](https://github.com/zcash/zcash/issues/2234). 13 | - `doc`: it contains some circuit schemes in ASCII (must be opened with Monodraw, an ASCII art editor for Mac). 14 | - `src`: it contains similar implementation of circuits in JavaScript. 15 | - `test`: tests. 16 | 17 | A description of the specific circuit templates for the `circuit` folder will be soon updated. -------------------------------------------------------------------------------- /circomlib/calcpedersenbases/calcpedersenbases.js: -------------------------------------------------------------------------------- 1 | const bn128 = require("snarkjs").bn128; 2 | const bigInt = require("snarkjs").bigInt; 3 | const createBlakeHash = require("blake-hash"); 4 | const babyJub = require("../src/babyjub"); 5 | 6 | function getPoint(S) { 7 | const F = bn128.Fr; 8 | const h = createBlakeHash("blake256").update(S).digest(); 9 | 10 | if (h.length != 32) { 11 | throw new Error("Invalid length") 12 | } 13 | 14 | let sign = false; 15 | if (h[31] & 0x80) { 16 | h[31] = h[31] & 0x7F; 17 | sign = true; 18 | } 19 | 20 | let y = bigInt(0); 21 | for (let i=0; i<32; i++) { 22 | y = y.shl(8); 23 | y = y.add(bigInt(h[i])); 24 | } 25 | 26 | const a = bigInt("168700"); 27 | const d = bigInt("168696"); 28 | 29 | const y2 = F.square(y); 30 | 31 | let x = F.sqrt(F.div( 32 | F.sub(F.one, y2), 33 | F.sub(a, F.mul(d, y2)))); 34 | 35 | if (x == null) return null; 36 | 37 | if (sign) x = F.neg(x); 38 | 39 | const p = [bn128.Fr.affine(x), bn128.Fr.affine(y)]; 40 | 41 | const p8 = babyJub.mulPointEscalar(p, 8); 42 | 43 | return p8; 44 | } 45 | 46 | 47 | function generatePoint(S) { 48 | let p= null; 49 | let idx = 0; 50 | while (p==null) { 51 | let sidx = "" + idx; 52 | while (sidx.length<16) sidx = "0"+sidx; 53 | p = getPoint(S+"_"+sidx); 54 | idx++; 55 | } 56 | if (!babyJub.inCurve(p)){ 57 | throw new Error("Point not in curve"); 58 | } 59 | return p; 60 | } 61 | 62 | 63 | 64 | 65 | 66 | const g = [ 67 | bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), 68 | bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]; 69 | 70 | // Sanity check 71 | if (!babyJub.inCurve(g)) { 72 | throw new Error("Generator not In curve -> Some thing goes wrong..."); 73 | } 74 | 75 | for (let i=0; i<25; i++) { 76 | let S = "" +i; 77 | while (S.length<16) S = "0"+S; 78 | const P = generatePoint("Iden3_PedersenGenerator_"+S); 79 | console.log(`[${P[0].toString()}, ${P[1].toString()}]`); 80 | } 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /circomlib/circuits/aliascheck.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "compconstant.circom"; 21 | 22 | 23 | template AliasCheck() { 24 | 25 | signal input in[254]; 26 | 27 | component compConstant = CompConstant(-1); 28 | 29 | for (var i=0; i<254; i++) in[i] ==> compConstant.in[i]; 30 | 31 | compConstant.out === 0; 32 | } 33 | -------------------------------------------------------------------------------- /circomlib/circuits/babyjub.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "bitify.circom"; 21 | include "escalarmulfix.circom"; 22 | 23 | template BabyAdd() { 24 | signal input x1; 25 | signal input y1; 26 | signal input x2; 27 | signal input y2; 28 | signal output xout; 29 | signal output yout; 30 | 31 | signal beta; 32 | signal gamma; 33 | signal delta; 34 | signal tau; 35 | 36 | var a = 168700; 37 | var d = 168696; 38 | 39 | beta <== x1*y2; 40 | gamma <== y1*x2; 41 | delta <== (-a*x1+y1)*(x2 + y2); 42 | tau <== beta * gamma; 43 | 44 | xout <-- (beta + gamma) / (1+ d*tau); 45 | (1+ d*tau) * xout === (beta + gamma); 46 | 47 | yout <-- (delta + a*beta - gamma) / (1-d*tau); 48 | (1-d*tau)*yout === (delta + a*beta - gamma); 49 | } 50 | 51 | template BabyDbl() { 52 | signal input x; 53 | signal input y; 54 | signal output xout; 55 | signal output yout; 56 | 57 | component adder = BabyAdd(); 58 | adder.x1 <== x; 59 | adder.y1 <== y; 60 | adder.x2 <== x; 61 | adder.y2 <== y; 62 | 63 | adder.xout ==> xout; 64 | adder.yout ==> yout; 65 | } 66 | 67 | 68 | template BabyCheck() { 69 | signal input x; 70 | signal input y; 71 | 72 | signal x2; 73 | signal y2; 74 | 75 | var a = 168700; 76 | var d = 168696; 77 | 78 | x2 <== x*x; 79 | y2 <== y*y; 80 | 81 | a*x2 + y2 === 1 + d*x2*y2; 82 | } 83 | 84 | // Extracts the public key from private key 85 | template BabyPbk() { 86 | signal private input in; 87 | signal output Ax; 88 | signal output Ay; 89 | 90 | var BASE8 = [ 91 | 5299619240641551281634865583518297030282874472190772894086521144482721001553, 92 | 16950150798460657717958625567821834550301663161624707787222815936182638968203 93 | ]; 94 | 95 | component pvkBits = Num2Bits(253); 96 | pvkBits.in <== in; 97 | 98 | component mulFix = EscalarMulFix(253, BASE8); 99 | 100 | var i; 101 | for (i=0; i<253; i++) { 102 | mulFix.e[i] <== pvkBits.out[i]; 103 | } 104 | Ax <== mulFix.out[0]; 105 | Ay <== mulFix.out[1]; 106 | } 107 | -------------------------------------------------------------------------------- /circomlib/circuits/binsub.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | /* 21 | This component creates a binary substraction. 22 | 23 | 24 | Main Constraint: 25 | (in[0][0] * 2^0 + in[0][1] * 2^1 + ..... + in[0][n-1] * 2^(n-1)) + 26 | + 2^n 27 | - (in[1][0] * 2^0 + in[1][1] * 2^1 + ..... + in[1][n-1] * 2^(n-1)) 28 | === 29 | out[0] * 2^0 + out[1] * 2^1 + + out[n-1] *2^(n-1) + aux 30 | 31 | 32 | out[0] * (out[0] - 1) === 0 33 | out[1] * (out[0] - 1) === 0 34 | . 35 | . 36 | . 37 | out[n-1] * (out[n-1] - 1) === 0 38 | aux * (aux-1) == 0 39 | 40 | */ 41 | 42 | template BinSub(n) { 43 | signal input in[2][n]; 44 | signal output out[n]; 45 | 46 | signal aux; 47 | 48 | var lin = 2**n; 49 | var lout = 0; 50 | 51 | for (var i=0; i> i) & 1; 58 | 59 | // Ensure out is binary 60 | out[i] * (out[i] - 1) === 0; 61 | 62 | lout = lout + out[i]*(2**i); 63 | } 64 | 65 | aux <-- (lin >> n) & 1; 66 | aux*(aux-1) === 0; 67 | lout = lout + aux*(2**n); 68 | 69 | // Ensure the sum; 70 | lin === lout; 71 | } 72 | -------------------------------------------------------------------------------- /circomlib/circuits/binsum.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | /* 21 | 22 | Binary Sum 23 | ========== 24 | 25 | This component creates a binary sum componet of ops operands and n bits each operand. 26 | 27 | e is Number of carries: Depends on the number of operands in the input. 28 | 29 | Main Constraint: 30 | in[0][0] * 2^0 + in[0][1] * 2^1 + ..... + in[0][n-1] * 2^(n-1) + 31 | + in[1][0] * 2^0 + in[1][1] * 2^1 + ..... + in[1][n-1] * 2^(n-1) + 32 | + .. 33 | + in[ops-1][0] * 2^0 + in[ops-1][1] * 2^1 + ..... + in[ops-1][n-1] * 2^(n-1) + 34 | === 35 | out[0] * 2^0 + out[1] * 2^1 + + out[n+e-1] *2(n+e-1) 36 | 37 | To waranty binary outputs: 38 | 39 | out[0] * (out[0] - 1) === 0 40 | out[1] * (out[0] - 1) === 0 41 | . 42 | . 43 | . 44 | out[n+e-1] * (out[n+e-1] - 1) == 0 45 | 46 | */ 47 | 48 | 49 | /* 50 | This function calculates the number of extra bits in the output to do the full sum. 51 | */ 52 | 53 | function nbits(a) { 54 | var n = 1; 55 | var r = 0; 56 | while (n-1> k) & 1; 83 | 84 | // Ensure out is binary 85 | out[k] * (out[k] - 1) === 0; 86 | 87 | lout += out[k] * 2**k; 88 | } 89 | 90 | // Ensure the sum; 91 | 92 | lin === lout; 93 | } 94 | -------------------------------------------------------------------------------- /circomlib/circuits/bitify.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "comparators.circom"; 21 | include "aliascheck.circom"; 22 | 23 | 24 | template Num2Bits(n) { 25 | signal input in; 26 | signal output out[n]; 27 | var lc1=0; 28 | 29 | for (var i = 0; i> i) & 1; 31 | out[i] * (out[i] -1 ) === 0; 32 | lc1 += out[i] * 2**i; 33 | } 34 | 35 | lc1 === in; 36 | } 37 | 38 | template Num2Bits_strict() { 39 | signal input in; 40 | signal output out[254]; 41 | 42 | component aliasCheck = AliasCheck(); 43 | component n2b = Num2Bits(254); 44 | in ==> n2b.in; 45 | 46 | for (var i=0; i<254; i++) { 47 | n2b.out[i] ==> out[i]; 48 | n2b.out[i] ==> aliasCheck.in[i]; 49 | } 50 | } 51 | 52 | template Bits2Num(n) { 53 | signal input in[n]; 54 | signal output out; 55 | var lc1=0; 56 | 57 | for (var i = 0; i out; 62 | } 63 | 64 | template Bits2Num_strict() { 65 | signal input in[n]; 66 | signal output out; 67 | 68 | component aliasCheck = AliasCheck(); 69 | component b2n = Bits2Num(254); 70 | 71 | for (var i=0; i<254; i++) { 72 | in[i] ==> b2n.in[i]; 73 | in[i] ==> aliasCheck.in[i]; 74 | } 75 | 76 | b2n.out ==> out; 77 | } 78 | 79 | template Num2BitsNeg(n) { 80 | signal input in; 81 | signal output out[n]; 82 | var lc1=0; 83 | 84 | component isZero; 85 | 86 | isZero = IsZero(); 87 | 88 | var neg = n == 0 ? 0 : 2**n - in; 89 | 90 | for (var i = 0; i> i) & 1; 92 | out[i] * (out[i] -1 ) === 0; 93 | lc1 += out[i] * 2**i; 94 | } 95 | 96 | in ==> isZero.in; 97 | 98 | 99 | 100 | lc1 + isZero.out * 2**n === 2**n - in; 101 | } 102 | -------------------------------------------------------------------------------- /circomlib/circuits/comparators.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "bitify.circom"; 21 | include "binsum.circom"; 22 | 23 | template IsZero() { 24 | signal input in; 25 | signal output out; 26 | 27 | signal inv; 28 | 29 | inv <-- in!=0 ? 1/in : 0; 30 | 31 | out <== -in*inv +1; 32 | in*out === 0; 33 | } 34 | 35 | 36 | template IsEqual() { 37 | signal input in[2]; 38 | signal output out; 39 | 40 | component isz = IsZero(); 41 | 42 | in[1] - in[0] ==> isz.in; 43 | 44 | isz.out ==> out; 45 | } 46 | 47 | template ForceEqualIfEnabled() { 48 | signal input enabled; 49 | signal input in[2]; 50 | 51 | component isz = IsZero(); 52 | 53 | in[1] - in[0] ==> isz.in; 54 | 55 | (1 - isz.out)*enabled === 0; 56 | } 57 | 58 | /* 59 | // N is the number of bits the input have. 60 | // The MSF is the sign bit. 61 | template LessThan(n) { 62 | signal input in[2]; 63 | signal output out; 64 | 65 | component num2Bits0; 66 | component num2Bits1; 67 | 68 | component adder; 69 | 70 | adder = BinSum(n, 2); 71 | 72 | num2Bits0 = Num2Bits(n); 73 | num2Bits1 = Num2BitsNeg(n); 74 | 75 | in[0] ==> num2Bits0.in; 76 | in[1] ==> num2Bits1.in; 77 | 78 | var i; 79 | for (i=0;i adder.in[0][i]; 81 | num2Bits1.out[i] ==> adder.in[1][i]; 82 | } 83 | 84 | adder.out[n-1] ==> out; 85 | } 86 | */ 87 | 88 | template LessThan(n) { 89 | signal input in[2]; 90 | signal output out; 91 | 92 | component n2b = Num2Bits(n*2+1); 93 | 94 | n2b.in <== in[0]+ (1< out; 112 | } 113 | 114 | // N is the number of bits the input have. 115 | // The MSF is the sign bit. 116 | template GreaterThan(n) { 117 | signal input in[2]; 118 | signal output out; 119 | 120 | component lt = LessThan(n); 121 | 122 | lt.in[0] <== in[1]; 123 | lt.in[1] <== in[0]; 124 | lt.out ==> out; 125 | } 126 | 127 | // N is the number of bits the input have. 128 | // The MSF is the sign bit. 129 | template GreaterEqThan(n) { 130 | signal input in[2]; 131 | signal output out; 132 | 133 | component lt = LessThan(n); 134 | 135 | lt.in[0] <== in[1]; 136 | lt.in[1] <== in[0]+1; 137 | lt.out ==> out; 138 | } 139 | 140 | -------------------------------------------------------------------------------- /circomlib/circuits/compconstant.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "bitify.circom"; 21 | 22 | // Returns 1 if in (in binary) > ct 23 | 24 | template CompConstant(ct) { 25 | signal input in[254]; 26 | signal output out; 27 | 28 | signal parts[127]; 29 | signal sout; 30 | 31 | var clsb; 32 | var cmsb; 33 | var slsb; 34 | var smsb; 35 | 36 | var sum=0; 37 | 38 | var b = (1 << 128) -1; 39 | var a = 1; 40 | var e = 1; 41 | var i; 42 | 43 | for (i=0;i<127; i++) { 44 | clsb = (ct >> (i*2)) & 1; 45 | cmsb = (ct >> (i*2+1)) & 1; 46 | slsb = in[i*2]; 47 | smsb = in[i*2+1]; 48 | 49 | 50 | if ((cmsb==0)&(clsb==0)) { 51 | parts[i] <== -b*smsb*slsb + b*smsb + b*slsb; 52 | } else if ((cmsb==0)&(clsb==1)) { 53 | parts[i] <== a*smsb*slsb - a*slsb + b*smsb - a*smsb + a; 54 | } else if ((cmsb==1)&(clsb==0)) { 55 | parts[i] <== b*smsb*slsb - a*smsb + a; 56 | } else { 57 | parts[i] <== -a*smsb*slsb + a; 58 | } 59 | 60 | sum = sum + parts[i]; 61 | 62 | b = b -e; 63 | a = a +e; 64 | e = e*2; 65 | } 66 | 67 | sout <== sum; 68 | 69 | component num2bits = Num2Bits(135); 70 | 71 | num2bits.in <== sout; 72 | 73 | out <== num2bits.out[127]; 74 | } 75 | -------------------------------------------------------------------------------- /circomlib/circuits/eddsamimc.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "compconstant.circom"; 21 | include "pointbits.circom"; 22 | include "mimc.circom"; 23 | include "bitify.circom"; 24 | include "escalarmulany.circom"; 25 | include "escalarmulfix.circom"; 26 | 27 | template EdDSAMiMCVerifier() { 28 | signal input enabled; 29 | signal input Ax; 30 | signal input Ay; 31 | 32 | signal input S; 33 | signal input R8x; 34 | signal input R8y; 35 | 36 | signal input M; 37 | 38 | var i; 39 | 40 | // Ensure S compConstant.in[i]; 49 | } 50 | compConstant.in[253] <== 0; 51 | compConstant.out === 0; 52 | 53 | // Calculate the h = H(R,A, msg) 54 | 55 | component hash = MultiMiMC7(5, 91); 56 | hash.in[0] <== R8x; 57 | hash.in[1] <== R8y; 58 | hash.in[2] <== Ax; 59 | hash.in[3] <== Ay; 60 | hash.in[4] <== M; 61 | hash.k <== 0; 62 | 63 | component h2bits = Num2Bits_strict(); 64 | h2bits.in <== hash.out; 65 | 66 | // Calculate second part of the right side: right2 = h*8*A 67 | 68 | // Multiply by 8 by adding it 3 times. This also ensure that the result is in 69 | // the subgroup. 70 | component dbl1 = BabyDbl(); 71 | dbl1.x <== Ax; 72 | dbl1.y <== Ay; 73 | component dbl2 = BabyDbl(); 74 | dbl2.x <== dbl1.xout; 75 | dbl2.y <== dbl1.yout; 76 | component dbl3 = BabyDbl(); 77 | dbl3.x <== dbl2.xout; 78 | dbl3.y <== dbl2.yout; 79 | 80 | // We check that A is not zero. 81 | component isZero = IsZero(); 82 | isZero.in <== dbl3.x; 83 | isZero.out === 0; 84 | 85 | component mulAny = EscalarMulAny(254); 86 | for (i=0; i<254; i++) { 87 | mulAny.e[i] <== h2bits.out[i]; 88 | } 89 | mulAny.p[0] <== dbl3.xout; 90 | mulAny.p[1] <== dbl3.yout; 91 | 92 | 93 | // Compute the right side: right = R8 + right2 94 | 95 | component addRight = BabyAdd(); 96 | addRight.x1 <== R8x; 97 | addRight.y1 <== R8y; 98 | addRight.x2 <== mulAny.out[0]; 99 | addRight.y2 <== mulAny.out[1]; 100 | 101 | // Calculate left side of equation left = S*B8 102 | 103 | var BASE8 = [ 104 | 5299619240641551281634865583518297030282874472190772894086521144482721001553, 105 | 16950150798460657717958625567821834550301663161624707787222815936182638968203 106 | ]; 107 | component mulFix = EscalarMulFix(253, BASE8); 108 | for (i=0; i<253; i++) { 109 | mulFix.e[i] <== snum2bits.out[i]; 110 | } 111 | 112 | // Do the comparation left == right if enabled; 113 | 114 | component eqCheckX = ForceEqualIfEnabled(); 115 | eqCheckX.enabled <== enabled; 116 | eqCheckX.in[0] <== mulFix.out[0]; 117 | eqCheckX.in[1] <== addRight.xout; 118 | 119 | component eqCheckY = ForceEqualIfEnabled(); 120 | eqCheckY.enabled <== enabled; 121 | eqCheckY.in[0] <== mulFix.out[1]; 122 | eqCheckY.in[1] <== addRight.yout; 123 | } 124 | -------------------------------------------------------------------------------- /circomlib/circuits/eddsamimcsponge.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "compconstant.circom"; 21 | include "pointbits.circom"; 22 | include "mimcsponge.circom"; 23 | include "bitify.circom"; 24 | include "escalarmulany.circom"; 25 | include "escalarmulfix.circom"; 26 | 27 | template EdDSAMiMCSpongeVerifier() { 28 | signal input enabled; 29 | signal input Ax; 30 | signal input Ay; 31 | 32 | signal input S; 33 | signal input R8x; 34 | signal input R8y; 35 | 36 | signal input M; 37 | 38 | var i; 39 | 40 | // Ensure S compConstant.in[i]; 49 | } 50 | compConstant.in[253] <== 0; 51 | compConstant.out === 0; 52 | 53 | // Calculate the h = H(R,A, msg) 54 | 55 | component hash = MiMCSponge(5, 220, 1); 56 | hash.ins[0] <== R8x; 57 | hash.ins[1] <== R8y; 58 | hash.ins[2] <== Ax; 59 | hash.ins[3] <== Ay; 60 | hash.ins[4] <== M; 61 | hash.k <== 0; 62 | 63 | component h2bits = Num2Bits_strict(); 64 | h2bits.in <== hash.outs[0]; 65 | 66 | // Calculate second part of the right side: right2 = h*8*A 67 | 68 | // Multiply by 8 by adding it 3 times. This also ensure that the result is in 69 | // the subgroup. 70 | component dbl1 = BabyDbl(); 71 | dbl1.x <== Ax; 72 | dbl1.y <== Ay; 73 | component dbl2 = BabyDbl(); 74 | dbl2.x <== dbl1.xout; 75 | dbl2.y <== dbl1.yout; 76 | component dbl3 = BabyDbl(); 77 | dbl3.x <== dbl2.xout; 78 | dbl3.y <== dbl2.yout; 79 | 80 | // We check that A is not zero. 81 | component isZero = IsZero(); 82 | isZero.in <== dbl3.x; 83 | isZero.out === 0; 84 | 85 | component mulAny = EscalarMulAny(254); 86 | for (i=0; i<254; i++) { 87 | mulAny.e[i] <== h2bits.out[i]; 88 | } 89 | mulAny.p[0] <== dbl3.xout; 90 | mulAny.p[1] <== dbl3.yout; 91 | 92 | 93 | // Compute the right side: right = R8 + right2 94 | 95 | component addRight = BabyAdd(); 96 | addRight.x1 <== R8x; 97 | addRight.y1 <== R8y; 98 | addRight.x2 <== mulAny.out[0]; 99 | addRight.y2 <== mulAny.out[1]; 100 | 101 | // Calculate left side of equation left = S*B8 102 | 103 | var BASE8 = [ 104 | 5299619240641551281634865583518297030282874472190772894086521144482721001553, 105 | 16950150798460657717958625567821834550301663161624707787222815936182638968203 106 | ]; 107 | component mulFix = EscalarMulFix(253, BASE8); 108 | for (i=0; i<253; i++) { 109 | mulFix.e[i] <== snum2bits.out[i]; 110 | } 111 | 112 | // Do the comparation left == right if enabled; 113 | 114 | component eqCheckX = ForceEqualIfEnabled(); 115 | eqCheckX.enabled <== enabled; 116 | eqCheckX.in[0] <== mulFix.out[0]; 117 | eqCheckX.in[1] <== addRight.xout; 118 | 119 | component eqCheckY = ForceEqualIfEnabled(); 120 | eqCheckY.enabled <== enabled; 121 | eqCheckY.in[0] <== mulFix.out[1]; 122 | eqCheckY.in[1] <== addRight.yout; 123 | } 124 | -------------------------------------------------------------------------------- /circomlib/circuits/eddsaposeidon.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "compconstant.circom"; 21 | include "poseidon.circom"; 22 | include "bitify.circom"; 23 | include "escalarmulany.circom"; 24 | include "escalarmulfix.circom"; 25 | 26 | template EdDSAPoseidonVerifier() { 27 | signal input enabled; 28 | signal input Ax; 29 | signal input Ay; 30 | 31 | signal input S; 32 | signal input R8x; 33 | signal input R8y; 34 | 35 | signal input M; 36 | 37 | var i; 38 | 39 | // Ensure S compConstant.in[i]; 48 | } 49 | compConstant.in[253] <== 0; 50 | compConstant.out*enabled === 0; 51 | 52 | // Calculate the h = H(R,A, msg) 53 | 54 | component hash = Poseidon(5, 6, 8, 57); 55 | 56 | hash.inputs[0] <== R8x; 57 | hash.inputs[1] <== R8y; 58 | hash.inputs[2] <== Ax; 59 | hash.inputs[3] <== Ay; 60 | hash.inputs[4] <== M; 61 | 62 | component h2bits = Num2Bits_strict(); 63 | h2bits.in <== hash.out; 64 | 65 | // Calculate second part of the right side: right2 = h*8*A 66 | 67 | // Multiply by 8 by adding it 3 times. This also ensure that the result is in 68 | // the subgroup. 69 | component dbl1 = BabyDbl(); 70 | dbl1.x <== Ax; 71 | dbl1.y <== Ay; 72 | component dbl2 = BabyDbl(); 73 | dbl2.x <== dbl1.xout; 74 | dbl2.y <== dbl1.yout; 75 | component dbl3 = BabyDbl(); 76 | dbl3.x <== dbl2.xout; 77 | dbl3.y <== dbl2.yout; 78 | 79 | // We check that A is not zero. 80 | component isZero = IsZero(); 81 | isZero.in <== dbl3.x; 82 | isZero.out*enabled === 0; 83 | 84 | component mulAny = EscalarMulAny(254); 85 | for (i=0; i<254; i++) { 86 | mulAny.e[i] <== h2bits.out[i]; 87 | } 88 | mulAny.p[0] <== dbl3.xout; 89 | mulAny.p[1] <== dbl3.yout; 90 | 91 | 92 | // Compute the right side: right = R8 + right2 93 | 94 | component addRight = BabyAdd(); 95 | addRight.x1 <== R8x; 96 | addRight.y1 <== R8y; 97 | addRight.x2 <== mulAny.out[0]; 98 | addRight.y2 <== mulAny.out[1]; 99 | 100 | // Calculate left side of equation left = S*B8 101 | 102 | var BASE8 = [ 103 | 5299619240641551281634865583518297030282874472190772894086521144482721001553, 104 | 16950150798460657717958625567821834550301663161624707787222815936182638968203 105 | ]; 106 | component mulFix = EscalarMulFix(253, BASE8); 107 | for (i=0; i<253; i++) { 108 | mulFix.e[i] <== snum2bits.out[i]; 109 | } 110 | 111 | // Do the comparation left == right if enabled; 112 | 113 | component eqCheckX = ForceEqualIfEnabled(); 114 | eqCheckX.enabled <== enabled; 115 | eqCheckX.in[0] <== mulFix.out[0]; 116 | eqCheckX.in[1] <== addRight.xout; 117 | 118 | component eqCheckY = ForceEqualIfEnabled(); 119 | eqCheckY.enabled <== enabled; 120 | eqCheckY.in[0] <== mulFix.out[1]; 121 | eqCheckY.in[1] <== addRight.yout; 122 | } 123 | -------------------------------------------------------------------------------- /circomlib/circuits/escalarmulw4table.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | function pointAdd(x1,y1,x2,y2) { 21 | var a = 168700; 22 | var d = 168696; 23 | 24 | var res[2]; 25 | res[0] = (x1*y2 + y1*x2) / (1 + d*x1*x2*y1*y2); 26 | res[1] = (y1*y2 - a*x1*x2) / (1 - d*x1*x2*y1*y2); 27 | return res; 28 | } 29 | 30 | template EscalarMulW4Table(base, k) { 31 | signal output out[16][2]; 32 | 33 | var i; 34 | var p[2]; 35 | 36 | var dbl = base; 37 | 38 | for (i=0; i. 18 | */ 19 | 20 | template XOR() { 21 | signal input a; 22 | signal input b; 23 | signal output out; 24 | 25 | out <== a + b - 2*a*b; 26 | } 27 | 28 | template AND() { 29 | signal input a; 30 | signal input b; 31 | signal output out; 32 | 33 | out <== a*b; 34 | } 35 | 36 | template OR() { 37 | signal input a; 38 | signal input b; 39 | signal output out; 40 | 41 | out <== a + b - a*b; 42 | } 43 | 44 | template NOT() { 45 | signal input in; 46 | signal output out; 47 | 48 | out <== 1 + in - 2*in; 49 | } 50 | 51 | template NAND() { 52 | signal input a; 53 | signal input b; 54 | signal output out; 55 | 56 | out <== 1 - a*b; 57 | } 58 | 59 | template NOR() { 60 | signal input a; 61 | signal input b; 62 | signal output out; 63 | 64 | out <== a*b + 1 - a - b; 65 | } 66 | 67 | template MultiAND(n) { 68 | signal input in[n]; 69 | signal output out; 70 | if (n==1) { 71 | out <== in[0]; 72 | } else if (n==2) { 73 | component and1 = AND(); 74 | and1.a <== in[0]; 75 | and1.b <== in[1]; 76 | out <== and1.out; 77 | } else { 78 | component and2 = AND(); 79 | component ands[2]; 80 | var n1 = n\2; 81 | var n2 = n-n\2; 82 | ands[0] = MultiAND(n1); 83 | ands[1] = MultiAND(n2); 84 | for (var i=0; i. 18 | */ 19 | 20 | /* 21 | Source: https://en.wikipedia.org/wiki/Montgomery_curve 22 | 23 | 1 + y 1 + y 24 | [u, v] = [ ------- , ---------- ] 25 | 1 - y (1 - y)x 26 | 27 | */ 28 | 29 | template Edwards2Montgomery() { 30 | signal input in[2]; 31 | signal output out[2]; 32 | 33 | out[0] <-- (1 + in[1]) / (1 - in[1]); 34 | out[1] <-- out[0] / in[0]; 35 | 36 | 37 | out[0] * (1-in[1]) === (1 + in[1]); 38 | out[1] * in[0] === out[0]; 39 | } 40 | 41 | /* 42 | 43 | u u - 1 44 | [x, y] = [ ---, ------- ] 45 | v u + 1 46 | 47 | */ 48 | template Montgomery2Edwards() { 49 | signal input in[2]; 50 | signal output out[2]; 51 | 52 | out[0] <-- in[0] / in[1]; 53 | out[1] <-- (in[0] - 1) / (in[0] + 1); 54 | 55 | out[0] * in[1] === in[0]; 56 | out[1] * (in[0] + 1) === in[0] - 1; 57 | } 58 | 59 | 60 | /* 61 | x2 - x1 62 | lamda = --------- 63 | y2 - y1 64 | 65 | x3 + A + x1 + x2 66 | x3 = B * lamda^2 - A - x1 -x2 => lamda^2 = ------------------ 67 | B 68 | 69 | y3 = (2*x1 + x2 + A)*lamda - B*lamda^3 - y1 => 70 | 71 | 72 | => y3 = lamda * ( 2*x1 + x2 + A - x3 - A - x1 - x2) - y1 => 73 | 74 | => y3 = lamda * ( x1 - x3 ) - y1 75 | 76 | ---------- 77 | 78 | y2 - y1 79 | lamda = --------- 80 | x2 - x1 81 | 82 | x3 = B * lamda^2 - A - x1 -x2 83 | 84 | y3 = lamda * ( x1 - x3 ) - y1 85 | 86 | */ 87 | 88 | template MontgomeryAdd() { 89 | signal input in1[2]; 90 | signal input in2[2]; 91 | signal output out[2]; 92 | 93 | var a = 168700; 94 | var d = 168696; 95 | 96 | var A = (2 * (a + d)) / (a - d); 97 | var B = 4 / (a - d); 98 | 99 | signal lamda; 100 | 101 | lamda <-- (in2[1] - in1[1]) / (in2[0] - in1[0]); 102 | lamda * (in2[0] - in1[0]) === (in2[1] - in1[1]); 103 | 104 | out[0] <== B*lamda*lamda - A - in1[0] -in2[0]; 105 | out[1] <== lamda * (in1[0] - out[0]) - in1[1]; 106 | } 107 | 108 | /* 109 | 110 | x1_2 = x1*x1 111 | 112 | 3*x1_2 + 2*A*x1 + 1 113 | lamda = --------------------- 114 | 2*B*y1 115 | 116 | x3 = B * lamda^2 - A - x1 -x1 117 | 118 | y3 = lamda * ( x1 - x3 ) - y1 119 | 120 | */ 121 | template MontgomeryDouble() { 122 | signal input in[2]; 123 | signal output out[2]; 124 | 125 | var a = 168700; 126 | var d = 168696; 127 | 128 | var A = (2 * (a + d)) / (a - d); 129 | var B = 4 / (a - d); 130 | 131 | signal lamda; 132 | signal x1_2; 133 | 134 | x1_2 <== in[0] * in[0]; 135 | 136 | lamda <-- (3*x1_2 + 2*A*in[0] + 1 ) / (2*B*in[1]); 137 | lamda * (2*B*in[1]) === (3*x1_2 + 2*A*in[0] + 1 ); 138 | 139 | out[0] <== B*lamda*lamda - A - 2*in[0]; 140 | out[1] <== lamda * (in[0] - out[0]) - in[1]; 141 | } 142 | -------------------------------------------------------------------------------- /circomlib/circuits/multiplexer.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | /* 21 | Copyright 2018 0KIMS association. 22 | 23 | This file is part of circom (Zero Knowledge Circuit Compiler). 24 | 25 | circom is a free software: you can redistribute it and/or modify it 26 | under the terms of the GNU General Public License as published by 27 | the Free Software Foundation, either version 3 of the License, or 28 | (at your option) any later version. 29 | 30 | circom is distributed in the hope that it will be useful, but WITHOUT 31 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 32 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 33 | License for more details. 34 | 35 | You should have received a copy of the GNU General Public License 36 | along with circom. If not, see . 37 | */ 38 | 39 | // --> Assignation without constraint 40 | // <-- Assignation without constraint 41 | // === Constraint 42 | // <== Assignation with constraint 43 | // ==> Assignation with constraint 44 | // All variables are members of the field F[p] 45 | // https://github.com/zcash-hackworks/sapling-crypto 46 | // https://github.com/ebfull/bellman 47 | 48 | /* 49 | function log2(a) { 50 | if (a==0) { 51 | return 0; 52 | } 53 | let n = 1; 54 | let r = 1; 55 | while (n success; 89 | success * (success -1) === 0; 90 | } 91 | 92 | 93 | template Multiplexer(wIn, nIn) { 94 | signal input inp[nIn][wIn]; 95 | signal input sel; 96 | signal output out[wIn]; 97 | component dec = Decoder(nIn); 98 | component ep[wIn]; 99 | 100 | for (var k=0; k dec.inp; 105 | for (var j=0; j ep[j].in1[k]; 108 | dec.out[k] ==> ep[j].in2[k]; 109 | } 110 | ep[j].out ==> out[j]; 111 | } 112 | dec.success === 1; 113 | } 114 | -------------------------------------------------------------------------------- /circomlib/circuits/mux1.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | template MultiMux1(n) { 21 | signal input c[n][2]; // Constants 22 | signal input s; // Selector 23 | signal output out[n]; 24 | 25 | for (var i=0; i mux.s; 45 | 46 | mux.out[0] ==> out; 47 | } 48 | -------------------------------------------------------------------------------- /circomlib/circuits/mux2.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | template MultiMux2(n) { 21 | signal input c[n][4]; // Constants 22 | signal input s[2]; // Selector 23 | signal output out[n]; 24 | 25 | signal a10[n]; 26 | signal a1[n]; 27 | signal a0[n]; 28 | signal a[n]; 29 | 30 | signal s10; 31 | s10 <== s[1] * s[0]; 32 | 33 | for (var i=0; i mux.s[i]; 59 | } 60 | 61 | mux.out[0] ==> out; 62 | } 63 | -------------------------------------------------------------------------------- /circomlib/circuits/mux3.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | template MultiMux3(n) { 21 | signal input c[n][8]; // Constants 22 | signal input s[3]; // Selector 23 | signal output out[n]; 24 | 25 | signal a210[n]; 26 | signal a21[n]; 27 | signal a20[n]; 28 | signal a2[n]; 29 | 30 | signal a10[n]; 31 | signal a1[n]; 32 | signal a0[n]; 33 | signal a[n]; 34 | 35 | // 4 constrains for the intermediary variables 36 | signal s10; 37 | s10 <== s[1] * s[0]; 38 | 39 | for (var i=0; i mux.s[i]; 71 | } 72 | 73 | mux.out[0] ==> out; 74 | } 75 | -------------------------------------------------------------------------------- /circomlib/circuits/pedersen_old.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "escalarmul.circom"; 21 | 22 | template Pedersen(n) { 23 | signal input in[n]; 24 | signal output out[2]; 25 | 26 | var nexps = ((n-1) \ 250) + 1; 27 | var nlastbits = n - (nexps-1)*250; 28 | 29 | component escalarMuls[nexps]; 30 | 31 | var PBASE = [ 32 | [10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317], 33 | [2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094], 34 | [5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896], 35 | [7107336197374528537877327281242680114152313102022415488494307685842428166594,2857869773864086953506483169737724679646433914307247183624878062391496185654], 36 | [20265828622013100949498132415626198973119240347465898028410217039057588424236,1160461593266035632937973507065134938065359936056410650153315956301179689506], 37 | [1487999857809287756929114517587739322941449154962237464737694709326309567994,14017256862867289575056460215526364897734808720610101650676790868051368668003], 38 | [14618644331049802168996997831720384953259095788558646464435263343433563860015,13115243279999696210147231297848654998887864576952244320558158620692603342236], 39 | [6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695], 40 | [3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506], 41 | [18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481] 42 | ]; 43 | 44 | var i; 45 | var j; 46 | var nexpbits; 47 | for (i=0; i out[0]; 65 | escalarMuls[nexps-1].out[1] ==> out[1]; 66 | } 67 | -------------------------------------------------------------------------------- /circomlib/circuits/sha256/ch.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | /* Ch 21 | 22 | 000 0 23 | 001 1 24 | 010 0 25 | 011 1 26 | 100 0 27 | 101 0 28 | 110 1 29 | 111 1 30 | 31 | out = a&b ^ (!a)&c => 32 | 33 | out = a*(b-c) + c 34 | 35 | */ 36 | 37 | template Ch(n) { 38 | signal input a[n]; 39 | signal input b[n]; 40 | signal input c[n]; 41 | signal output out[n]; 42 | 43 | for (var k=0; k. 18 | */ 19 | 20 | template H(x) { 21 | signal output out[32]; 22 | var c = [0x6a09e667, 23 | 0xbb67ae85, 24 | 0x3c6ef372, 25 | 0xa54ff53a, 26 | 0x510e527f, 27 | 0x9b05688c, 28 | 0x1f83d9ab, 29 | 0x5be0cd19]; 30 | 31 | for (var i=0; i<32; i++) { 32 | out[i] <== (c[x] >> i) & 1; 33 | } 34 | } 35 | 36 | template K(x) { 37 | signal output out[32]; 38 | var c = [ 39 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 40 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 41 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 42 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 43 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 44 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 45 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 46 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 47 | ]; 48 | 49 | for (var i=0; i<32; i++) { 50 | out[i] <== (c[x] >> i) & 1; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /circomlib/circuits/sha256/main.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "sha256_2.jaz"; 21 | 22 | template Main() { 23 | signal private input a; 24 | signal private input b; 25 | signal output out; 26 | 27 | component sha256_2 = SHA256_2(); 28 | 29 | sha256_2.a <== a; 30 | sha256_2.b <== a; 31 | out <== sha256_2.out; 32 | } 33 | 34 | component main = Main(); 35 | -------------------------------------------------------------------------------- /circomlib/circuits/sha256/maj.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | /* Maj function for sha256 21 | 22 | out = a&b ^ a&c ^ b&c => 23 | 24 | out = a*b + a*c + b*c - 2*a*b*c => 25 | 26 | out = a*( b + c - 2*b*c ) + b*c => 27 | 28 | mid = b*c 29 | out = a*( b + c - 2*mid ) + mid 30 | 31 | */ 32 | 33 | template Maj(n) { 34 | signal input a[n]; 35 | signal input b[n]; 36 | signal input c[n]; 37 | signal output out[n]; 38 | signal mid[n]; 39 | 40 | for (var k=0; k. 18 | */ 19 | 20 | template RotR(n, r) { 21 | signal input in[n]; 22 | signal output out[n]; 23 | 24 | for (var i=0; i> k)&1; 31 | } 32 | 33 | component ha0 = H(0); 34 | component hb0 = H(1); 35 | component hc0 = H(2); 36 | component hd0 = H(3); 37 | component he0 = H(4); 38 | component hf0 = H(5); 39 | component hg0 = H(6); 40 | component hh0 = H(7); 41 | 42 | component sha256compression[nBlocks]; 43 | 44 | for (i=0; i. 18 | */ 19 | 20 | include "constants.circom"; 21 | include "sha256compression.circom"; 22 | include "../bitify.circom" 23 | 24 | template Sha256_2() { 25 | signal input a; 26 | signal input b; 27 | signal output out; 28 | 29 | var i; 30 | var k; 31 | 32 | component bits2num = Bits2Num(216); 33 | component num2bits[2]; 34 | 35 | num2bits[0] = Num2Bits(216); 36 | num2bits[1] = Num2Bits(216); 37 | 38 | num2bits[0].in <== a; 39 | num2bits[1].in <== b; 40 | 41 | 42 | component sha256compression = Sha256compression() ; 43 | 44 | component ha0 = H(0); 45 | component hb0 = H(1); 46 | component hc0 = H(2); 47 | component hd0 = H(3); 48 | component he0 = H(4); 49 | component hf0 = H(5); 50 | component hg0 = H(6); 51 | component hh0 = H(7); 52 | 53 | for (k=0; k<32; k++ ) { 54 | sha256compression.hin[0*32+k] <== ha0.out[k]; 55 | sha256compression.hin[1*32+k] <== hb0.out[k]; 56 | sha256compression.hin[2*32+k] <== hc0.out[k]; 57 | sha256compression.hin[3*32+k] <== hd0.out[k]; 58 | sha256compression.hin[4*32+k] <== he0.out[k]; 59 | sha256compression.hin[5*32+k] <== hf0.out[k]; 60 | sha256compression.hin[6*32+k] <== hg0.out[k]; 61 | sha256compression.hin[7*32+k] <== hh0.out[k]; 62 | } 63 | 64 | for (i=0; i<216; i++) { 65 | sha256compression.inp[i] <== num2bits[0].out[215-i]; 66 | sha256compression.inp[i+216] <== num2bits[1].out[215-i]; 67 | } 68 | 69 | sha256compression.inp[432] <== 1; 70 | 71 | for (i=433; i<503; i++) { 72 | sha256compression.inp[i] <== 0; 73 | } 74 | 75 | sha256compression.inp[503] <== 1; 76 | sha256compression.inp[504] <== 1; 77 | sha256compression.inp[505] <== 0; 78 | sha256compression.inp[506] <== 1; 79 | sha256compression.inp[507] <== 1; 80 | sha256compression.inp[508] <== 0; 81 | sha256compression.inp[509] <== 0; 82 | sha256compression.inp[510] <== 0; 83 | sha256compression.inp[511] <== 0; 84 | 85 | for (i=0; i<216; i++) { 86 | bits2num.in[i] <== sha256compression.out[255-i]; 87 | } 88 | 89 | out <== bits2num.out; 90 | } 91 | -------------------------------------------------------------------------------- /circomlib/circuits/sha256/shift.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | template ShR(n, r) { 21 | signal input in[n]; 22 | signal output out[n]; 23 | 24 | for (var i=0; i= n) { 26 | out[i] <== 0; 27 | } else { 28 | out[i] <== in[ i+r ]; 29 | } 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /circomlib/circuits/sha256/sigma.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "xor3.circom"; 21 | include "rotate.circom"; 22 | include "shift.circom"; 23 | 24 | template SmallSigma(ra, rb, rc) { 25 | signal input in[32]; 26 | signal output out[32]; 27 | 28 | component xor3 = Xor3(32); 29 | 30 | component rota = RotR(32, ra); 31 | component rotb = RotR(32, rb); 32 | component shrc = ShR(32, rc); 33 | 34 | for (var k=0; k<32; k++) { 35 | rota.in[k] <== in[k]; 36 | rotb.in[k] <== in[k]; 37 | shrc.in[k] <== in[k]; 38 | 39 | xor3.a[k] <== rota.out[k]; 40 | xor3.b[k] <== rotb.out[k]; 41 | xor3.c[k] <== shrc.out[k]; 42 | 43 | out[k] <== xor3.out[k]; 44 | } 45 | } 46 | 47 | template BigSigma(ra, rb, rc) { 48 | signal input in[32]; 49 | signal output out[32]; 50 | 51 | component xor3 = Xor3(32); 52 | 53 | component rota = RotR(32, ra); 54 | component rotb = RotR(32, rb); 55 | component rotc = RotR(32, rc); 56 | 57 | for (var k=0; k<32; k++) { 58 | rota.in[k] <== in[k]; 59 | rotb.in[k] <== in[k]; 60 | rotc.in[k] <== in[k]; 61 | 62 | xor3.a[k] <== rota.out[k]; 63 | xor3.b[k] <== rotb.out[k]; 64 | xor3.c[k] <== rotc.out[k]; 65 | 66 | out[k] <== xor3.out[k]; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /circomlib/circuits/sha256/sigmaplus.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "../binsum.circom" 21 | include "sigma.circom" 22 | 23 | template SigmaPlus() { 24 | signal input in2[32]; 25 | signal input in7[32]; 26 | signal input in15[32]; 27 | signal input in16[32]; 28 | signal output out[32]; 29 | 30 | component sum = BinSum(32, 4); 31 | component sigma1 = SmallSigma(17,19,10); 32 | component sigma0 = SmallSigma(7, 18, 3); 33 | 34 | for (var k=0; k<32; k++) { 35 | sigma1.in[k] <== in2[k]; 36 | sigma0.in[k] <== in15[k]; 37 | 38 | sum.in[0][k] <== sigma1.out[k]; 39 | sum.in[1][k] <== in7[k]; 40 | sum.in[2][k] <== sigma0.out[k]; 41 | sum.in[3][k] <== in16[k]; 42 | 43 | out[k] <== sum.out[k]; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /circomlib/circuits/sha256/t1.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "../binsum.circom"; 21 | include "sigma.circom"; 22 | include "ch.circom"; 23 | 24 | template T1() { 25 | signal input h[32]; 26 | signal input e[32]; 27 | signal input f[32]; 28 | signal input g[32]; 29 | signal input k[32]; 30 | signal input w[32]; 31 | signal output out[32]; 32 | 33 | component sum = BinSum(32, 5); 34 | component ch = Ch(32); 35 | 36 | component bigsigma1 = BigSigma(6, 11, 25); 37 | 38 | for (var ki=0; ki<32; ki++) { 39 | bigsigma1.in[ki] <== e[ki]; 40 | ch.a[ki] <== e[ki]; 41 | ch.b[ki] <== f[ki]; 42 | ch.c[ki] <== g[ki] 43 | 44 | sum.in[0][ki] <== h[ki]; 45 | sum.in[1][ki] <== bigsigma1.out[ki]; 46 | sum.in[2][ki] <== ch.out[ki]; 47 | sum.in[3][ki] <== k[ki]; 48 | sum.in[4][ki] <== w[ki]; 49 | 50 | out[ki] <== sum.out[ki]; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /circomlib/circuits/sha256/t2.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "../binsum.circom"; 21 | include "sigma.circom"; 22 | include "maj.circom" 23 | 24 | template T2() { 25 | signal input a[32]; 26 | signal input b[32]; 27 | signal input c[32]; 28 | signal output out[32]; 29 | 30 | component sum = BinSum(32, 2); 31 | 32 | component bigsigma0 = BigSigma(2, 13, 22); 33 | component maj = Maj(32); 34 | 35 | for (var k=0; k<32; k++) { 36 | 37 | bigsigma0.in[k] <== a[k]; 38 | maj.a[k] <== a[k]; 39 | maj.b[k] <== b[k]; 40 | maj.c[k] <== c[k]; 41 | 42 | sum.in[0][k] <== bigsigma0.out[k]; 43 | sum.in[1][k] <== maj.out[k]; 44 | 45 | out[k] <== sum.out[k]; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /circomlib/circuits/sha256/xor3.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | /* Xor3 function for sha256 21 | 22 | out = a ^ b ^ c => 23 | 24 | out = a+b+c - 2*a*b - 2*a*c - 2*b*c + 4*a*b*c => 25 | 26 | out = a*( 1 - 2*b - 2*c + 4*b*c ) + b + c - 2*b*c => 27 | 28 | mid = b*c 29 | out = a*( 1 - 2*b -2*c + 4*mid ) + b + c - 2 * mid 30 | 31 | */ 32 | 33 | template Xor3(n) { 34 | signal input a[n]; 35 | signal input b[n]; 36 | signal input c[n]; 37 | signal output out[n]; 38 | signal mid[n]; 39 | 40 | for (var k=0; k. 18 | */ 19 | 20 | include "compconstant.circom"; 21 | 22 | template Sign() { 23 | signal input in[254]; 24 | signal output sign; 25 | 26 | component comp = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808); 27 | 28 | var i; 29 | 30 | for (i=0; i<254; i++) { 31 | comp.in[i] <== in[i]; 32 | } 33 | 34 | sign <== comp.out; 35 | } 36 | -------------------------------------------------------------------------------- /circomlib/circuits/smt/smthash_mimc.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "../mimc.circom"; 21 | 22 | 23 | /* 24 | Hash1 = H(1 | key | value) 25 | */ 26 | 27 | template SMTHash1() { 28 | signal input key; 29 | signal input value; 30 | signal output out; 31 | 32 | component h = MultiMiMC7(2, 91); // Constant 33 | h.in[0] <== key; 34 | h.in[1] <== value; 35 | h.k <== 1; 36 | 37 | out <== h.out; 38 | } 39 | 40 | /* 41 | This component is used to create the 2 nodes. 42 | 43 | Hash2 = H(Hl | Hr) 44 | */ 45 | 46 | template SMTHash2() { 47 | signal input L; 48 | signal input R; 49 | signal output out; 50 | 51 | component h = MultiMiMC7(2, 91); // Constant 52 | h.in[0] <== L; 53 | h.in[1] <== R; 54 | h.k <== 0; 55 | 56 | out <== h.out; 57 | } 58 | -------------------------------------------------------------------------------- /circomlib/circuits/smt/smthash_poseidon.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | include "../poseidon.circom"; 21 | 22 | 23 | /* 24 | Hash1 = H(1 | key | value) 25 | */ 26 | 27 | template SMTHash1() { 28 | signal input key; 29 | signal input value; 30 | signal output out; 31 | 32 | component h = Poseidon(3, 6, 8, 57); // Constant 33 | h.inputs[0] <== key; 34 | h.inputs[1] <== value; 35 | h.inputs[2] <== 1; 36 | 37 | out <== h.out; 38 | } 39 | 40 | /* 41 | This component is used to create the 2 nodes. 42 | 43 | Hash2 = H(Hl | Hr) 44 | */ 45 | 46 | template SMTHash2() { 47 | signal input L; 48 | signal input R; 49 | signal output out; 50 | 51 | component h = Poseidon(2, 6, 8, 57); // Constant 52 | h.inputs[0] <== L; 53 | h.inputs[1] <== R; 54 | 55 | out <== h.out; 56 | } 57 | -------------------------------------------------------------------------------- /circomlib/circuits/smt/smtlevins.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | /* 21 | 22 | This component finds the level where the oldInsert is done. 23 | The rules are: 24 | 25 | levIns[i] == 1 if its level and all the child levels have a sibling of 0 and 26 | the parent level has a sibling != 0. Considere that the root level always has 27 | a parent with a sibling != 0. 28 | 29 | 30 | ┌──────────────┐ 31 | │ │ 32 | │ │───▶ levIns[0] <== (1-done[i]) 33 | │ │ 34 | └──────────────┘ 35 | ▲ 36 | │ 37 | │ 38 | done[0] 39 | 40 | 41 | 42 | done[i-1] <== levIns[i] + done[i] 43 | ▲ 44 | │ 45 | │ 46 | ┌───────────┐ ┌──────────────┐ 47 | │ │ │ │ 48 | sibling[i-1]───▶│IsZero[i-1]│─▶│ │───▶ levIns[i] <== (1-done[i])*(1-isZero[i-1].out) 49 | │ │ │ │ 50 | └───────────┘ └──────────────┘ 51 | ▲ 52 | │ 53 | │ 54 | done[i] 55 | 56 | 57 | 58 | done[n-2] <== levIns[n-1] 59 | ▲ 60 | │ 61 | │ 62 | ┌───────────┐ ┌──────────────┐ 63 | │ │ │ │ 64 | sibling[n-2]───▶│IsZero[n-2]│─▶│ │────▶ levIns[n-1] <== (1-isZero[n-2].out) 65 | │ │ │ │ 66 | └───────────┘ └──────────────┘ 67 | 68 | ┌───────────┐ 69 | │ │ 70 | sibling[n-1]───▶│IsZero[n-1]│────▶ === 0 71 | │ │ 72 | └───────────┘ 73 | 74 | */ 75 | 76 | template SMTLevIns(nLevels) { 77 | signal input enabled; 78 | signal input siblings[nLevels]; 79 | signal output levIns[nLevels]; 80 | signal done[nLevels-1]; // Indicates if the insLevel has aready been detected. 81 | 82 | component isZero[nLevels]; 83 | 84 | for (var i=0; i0; i--) { 95 | levIns[i] <== (1-done[i])*(1-isZero[i-1].out) 96 | done[i-1] <== levIns[i] + done[i]; 97 | } 98 | 99 | levIns[0] <== (1-done[0]); 100 | } 101 | -------------------------------------------------------------------------------- /circomlib/circuits/smt/smtprocessorlevel.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | /****** 21 | 22 | SMTProcessorLevel 23 | 24 | This circuit has 2 hash 25 | 26 | Outputs according to the state. 27 | 28 | State oldRoot newRoot 29 | ===== ======= ======= 30 | top H'(oldChild, sibling) H'(newChild, sibling) 31 | old0 0 new1leaf 32 | bot old1leaf H'(newChild, 0) 33 | new1 old1leaf H'(new1leaf, old1leaf) 34 | na 0 0 35 | 36 | upd old1leaf new1leaf 37 | 38 | H' is the Hash function with the inputs shifted acordingly. 39 | 40 | *****/ 41 | 42 | 43 | template SMTProcessorLevel() { 44 | signal input st_top; 45 | signal input st_old0; 46 | signal input st_bot; 47 | signal input st_new1; 48 | signal input st_na; 49 | signal input st_upd; 50 | 51 | signal output oldRoot; 52 | signal output newRoot; 53 | signal input sibling; 54 | signal input old1leaf; 55 | signal input new1leaf; 56 | signal input newlrbit; 57 | signal input oldChild; 58 | signal input newChild; 59 | 60 | signal aux[4]; 61 | 62 | component oldProofHash = SMTHash2(); 63 | component newProofHash = SMTHash2(); 64 | 65 | component oldSwitcher = Switcher(); 66 | component newSwitcher = Switcher(); 67 | 68 | // Old side 69 | 70 | oldSwitcher.L <== oldChild; 71 | oldSwitcher.R <== sibling; 72 | 73 | oldSwitcher.sel <== newlrbit; 74 | oldProofHash.L <== oldSwitcher.outL; 75 | oldProofHash.R <== oldSwitcher.outR; 76 | 77 | aux[0] <== old1leaf * (st_bot + st_new1 + st_upd); 78 | oldRoot <== aux[0] + oldProofHash.out * st_top; 79 | 80 | // New side 81 | 82 | aux[1] <== newChild * ( st_top + st_bot); 83 | newSwitcher.L <== aux[1] + new1leaf*st_new1; 84 | 85 | aux[2] <== sibling*st_top; 86 | newSwitcher.R <== aux[2] + old1leaf*st_new1; 87 | 88 | newSwitcher.sel <== newlrbit; 89 | newProofHash.L <== newSwitcher.outL; 90 | newProofHash.R <== newSwitcher.outR; 91 | 92 | aux[3] <== newProofHash.out * (st_top + st_bot + st_new1); 93 | newRoot <== aux[3] + new1leaf * (st_old0 + st_upd); 94 | } 95 | -------------------------------------------------------------------------------- /circomlib/circuits/smt/smtverifierlevel.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | /****** 21 | 22 | SMTVerifierLevel 23 | 24 | This circuit has 1 hash 25 | 26 | Outputs according to the state. 27 | 28 | State root 29 | ===== ======= 30 | top H'(child, sibling) 31 | i0 0 32 | iold old1leaf 33 | inew new1leaf 34 | na 0 35 | 36 | H' is the Hash function with the inputs shifted acordingly. 37 | 38 | *****/ 39 | 40 | 41 | template SMTVerifierLevel() { 42 | signal input st_top; 43 | signal input st_i0; 44 | signal input st_iold; 45 | signal input st_inew; 46 | signal input st_na; 47 | 48 | signal output root; 49 | signal input sibling; 50 | signal input old1leaf; 51 | signal input new1leaf; 52 | signal input lrbit; 53 | signal input child; 54 | 55 | signal aux[2]; 56 | 57 | component proofHash = SMTHash2(); 58 | component switcher = Switcher(); 59 | 60 | switcher.L <== child; 61 | switcher.R <== sibling; 62 | 63 | switcher.sel <== lrbit; 64 | proofHash.L <== switcher.outL; 65 | proofHash.R <== switcher.outR; 66 | 67 | aux[0] <== proofHash.out * st_top; 68 | aux[1] <== old1leaf*st_iold; 69 | 70 | root <== aux[0] + aux[1] + new1leaf*st_inew; 71 | } 72 | -------------------------------------------------------------------------------- /circomlib/circuits/switcher.circom: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 0KIMS association. 3 | 4 | This file is part of circom (Zero Knowledge Circuit Compiler). 5 | 6 | circom is a free software: you can redistribute it and/or modify it 7 | under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | circom is distributed in the hope that it will be useful, but WITHOUT 12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 | License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with circom. If not, see . 18 | */ 19 | 20 | /* 21 | Assume sel is binary. 22 | 23 | If sel == 0 then outL = L and outR=R 24 | If sel == 1 then outL = R and outR=L 25 | 26 | */ 27 | 28 | template Switcher() { 29 | signal input sel; 30 | signal input L; 31 | signal input R; 32 | signal output outL; 33 | signal output outR; 34 | 35 | signal aux; 36 | 37 | aux <== (R-L)*sel; // We create aux in order to have only one multiplication 38 | outL <== aux + L; 39 | outR <== -aux + R; 40 | } 41 | -------------------------------------------------------------------------------- /circomlib/doc/root_transfer.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gcc2ge/MIXER-SAMPLE/f25c9e5a6da1e8c3f7d8a7a3580a644dc9a892ac/circomlib/doc/root_transfer.monopic -------------------------------------------------------------------------------- /circomlib/doc/smt_diagram_0.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gcc2ge/MIXER-SAMPLE/f25c9e5a6da1e8c3f7d8a7a3580a644dc9a892ac/circomlib/doc/smt_diagram_0.monopic -------------------------------------------------------------------------------- /circomlib/doc/smt_diagram_1.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gcc2ge/MIXER-SAMPLE/f25c9e5a6da1e8c3f7d8a7a3580a644dc9a892ac/circomlib/doc/smt_diagram_1.monopic -------------------------------------------------------------------------------- /circomlib/doc/smt_hash.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gcc2ge/MIXER-SAMPLE/f25c9e5a6da1e8c3f7d8a7a3580a644dc9a892ac/circomlib/doc/smt_hash.monopic -------------------------------------------------------------------------------- /circomlib/doc/smt_levins.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gcc2ge/MIXER-SAMPLE/f25c9e5a6da1e8c3f7d8a7a3580a644dc9a892ac/circomlib/doc/smt_levins.monopic -------------------------------------------------------------------------------- /circomlib/doc/smt_sm.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gcc2ge/MIXER-SAMPLE/f25c9e5a6da1e8c3f7d8a7a3580a644dc9a892ac/circomlib/doc/smt_sm.monopic -------------------------------------------------------------------------------- /circomlib/doc/smt_verifier_sm.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gcc2ge/MIXER-SAMPLE/f25c9e5a6da1e8c3f7d8a7a3580a644dc9a892ac/circomlib/doc/smt_verifier_sm.monopic -------------------------------------------------------------------------------- /circomlib/doc/voting.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gcc2ge/MIXER-SAMPLE/f25c9e5a6da1e8c3f7d8a7a3580a644dc9a892ac/circomlib/doc/voting.monopic -------------------------------------------------------------------------------- /circomlib/doc/window.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gcc2ge/MIXER-SAMPLE/f25c9e5a6da1e8c3f7d8a7a3580a644dc9a892ac/circomlib/doc/window.monopic -------------------------------------------------------------------------------- /circomlib/doc/window_chain.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gcc2ge/MIXER-SAMPLE/f25c9e5a6da1e8c3f7d8a7a3580a644dc9a892ac/circomlib/doc/window_chain.monopic -------------------------------------------------------------------------------- /circomlib/index.js: -------------------------------------------------------------------------------- 1 | exports.smt = require("./src/smt"); 2 | exports.eddsa = require("./src/eddsa"); 3 | exports.mimc7 = require("./src/mimc7"); 4 | exports.mimcsponge = require("./src/mimcsponge"); 5 | exports.babyJub = require("./src/babyjub"); 6 | exports.pedersenHash = require("./src/pedersenHash"); 7 | exports.SMT = require("./src/smt").SMT; 8 | exports.SMTMemDB = require("./src/smt_memdb"); 9 | exports.poseidon = require("./src/poseidon"); 10 | -------------------------------------------------------------------------------- /circomlib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "circomlib", 3 | "version": "0.0.19", 4 | "description": "Basic circuits library for Circom", 5 | "main": "index.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "mocha --max-old-space-size=4000" 11 | }, 12 | "keywords": [ 13 | "pedersen", 14 | "hash", 15 | "ethereum", 16 | "circuit", 17 | "circom", 18 | "zksnark" 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/iden3/circomlib.git" 23 | }, 24 | "author": "0Kims", 25 | "license": "GPL-3.0", 26 | "dependencies": { 27 | "blake-hash": "^1.1.0", 28 | "blake2b": "^2.1.3", 29 | "snarkjs": "^0.1.20", 30 | "typedarray-to-buffer": "^3.1.5", 31 | "web3": "^1.0.0-beta.55" 32 | }, 33 | "devDependencies": { 34 | "circom": "0.0.34", 35 | "eslint-plugin-mocha": "^5.2.0", 36 | "ganache-cli": "^6.4.4", 37 | "mocha": "^5.2.0" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /circomlib/src/babyjub.js: -------------------------------------------------------------------------------- 1 | const bn128 = require("snarkjs").bn128; 2 | const bigInt = require("snarkjs").bigInt; 3 | 4 | exports.addPoint = addPoint; 5 | exports.mulPointEscalar = mulPointEscalar; 6 | exports.inCurve = inCurve; 7 | exports.inSubgroup = inSubgroup; 8 | exports.packPoint = packPoint; 9 | exports.unpackPoint = unpackPoint; 10 | exports.Generator = [ 11 | bigInt("995203441582195749578291179787384436505546430278305826713579947235728471134"), 12 | bigInt("5472060717959818805561601436314318772137091100104008585924551046643952123905") 13 | ]; 14 | exports.Base8 = [ 15 | bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), 16 | bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203") 17 | ]; 18 | exports.order = bigInt("21888242871839275222246405745257275088614511777268538073601725287587578984328"); 19 | exports.subOrder = exports.order.shr(3); 20 | exports.p = bn128.r; 21 | exports.A = bigInt("168700"); 22 | exports.D = bigInt("168696"); 23 | 24 | 25 | function addPoint(a,b) { 26 | const q = bn128.r; 27 | 28 | const res = []; 29 | 30 | /* does the equivalent of: 31 | res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt("1") + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q); 32 | res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt("1") - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q); 33 | */ 34 | res[0] = bigInt((bigInt(a[0]).mul(b[1]).add(bigInt(b[0]).mul(a[1]))).mul(bigInt(bigInt("1").add(exports.D.mul(a[0]).mul(b[0]).mul(a[1]).mul(b[1]))).inverse(q))).affine(q); 35 | res[1] = bigInt((bigInt(a[1]).mul(b[1]).sub(exports.A.mul(a[0]).mul(b[0]))).mul(bigInt(bigInt("1").sub(exports.D.mul(a[0]).mul(b[0]).mul(a[1]).mul(b[1]))).inverse(q))).affine(q); 36 | 37 | return res; 38 | } 39 | 40 | function mulPointEscalar(base, e) { 41 | let res = [bigInt("0"),bigInt("1")]; 42 | let rem = bigInt(e); 43 | let exp = base; 44 | 45 | while (! rem.isZero()) { 46 | if (rem.isOdd()) { 47 | res = addPoint(res, exp); 48 | } 49 | exp = addPoint(exp, exp); 50 | rem = rem.shr(1); 51 | } 52 | 53 | return res; 54 | } 55 | 56 | function inSubgroup(P) { 57 | if (!inCurve(P)) return false; 58 | const res= mulPointEscalar(P, exports.subOrder); 59 | return (res[0].equals(bigInt(0))) && (res[1].equals(bigInt(1))); 60 | } 61 | 62 | function inCurve(P) { 63 | const F = bn128.Fr; 64 | 65 | const x2 = F.square(P[0]); 66 | const y2 = F.square(P[1]); 67 | 68 | if (!F.equals( 69 | F.add(F.mul(exports.A, x2), y2), 70 | F.add(F.one, F.mul(F.mul(x2, y2), exports.D)))) return false; 71 | 72 | return true; 73 | } 74 | 75 | function packPoint(P) { 76 | const buff = bigInt.leInt2Buff(P[1], 32); 77 | if (P[0].greater(exports.p.shr(1))) { 78 | buff[31] = buff[31] | 0x80; 79 | } 80 | return buff; 81 | } 82 | 83 | function unpackPoint(_buff) { 84 | const F = bn128.Fr; 85 | 86 | const buff = Buffer.from(_buff); 87 | let sign = false; 88 | const P = new Array(2); 89 | if (buff[31] & 0x80) { 90 | sign = true; 91 | buff[31] = buff[31] & 0x7F; 92 | } 93 | P[1] = bigInt.leBuff2int(buff); 94 | if (P[1].greaterOrEquals(exports.p)) return null; 95 | 96 | const y2 = F.square(P[1]); 97 | 98 | let x = F.sqrt(F.div( 99 | F.sub(F.one, y2), 100 | F.sub(exports.A, F.mul(exports.D, y2)))); 101 | 102 | if (x == null) return null; 103 | 104 | if (sign) x = F.neg(x); 105 | 106 | P[0] = F.affine(x); 107 | 108 | return P; 109 | } 110 | -------------------------------------------------------------------------------- /circomlib/src/mimc7.js: -------------------------------------------------------------------------------- 1 | const bn128 = require("snarkjs").bn128; 2 | const bigInt = require("snarkjs").bigInt; 3 | const Web3Utils = require("web3-utils"); 4 | const F = bn128.Fr; 5 | 6 | const SEED = "mimc"; 7 | const NROUNDS = 91; 8 | 9 | exports.getIV = (seed) => { 10 | if (typeof seed === "undefined") seed = SEED; 11 | const c = Web3Utils.keccak256(seed+"_iv"); 12 | const cn = bigInt(Web3Utils.toBN(c).toString()); 13 | const iv = cn.mod(F.q); 14 | return iv; 15 | }; 16 | 17 | exports.getConstants = (seed, nRounds) => { 18 | if (typeof seed === "undefined") seed = SEED; 19 | if (typeof nRounds === "undefined") nRounds = NROUNDS; 20 | const cts = new Array(nRounds); 21 | let c = Web3Utils.keccak256(SEED); 22 | for (let i=1; i{ 36 | const x_in = bigInt(_x_in); 37 | const k = bigInt(_k); 38 | let r; 39 | for (let i=0; i { 48 | let r; 49 | if (typeof(key) === "undefined") { 50 | r = F.zero; 51 | } else { 52 | r = key; 53 | } 54 | for (let i=0; i { 10 | if (typeof seed === "undefined") seed = SEED; 11 | const c = Web3Utils.keccak256(seed+"_iv"); 12 | const cn = bigInt(Web3Utils.toBN(c).toString()); 13 | const iv = cn.mod(F.q); 14 | return iv; 15 | }; 16 | 17 | exports.getConstants = (seed, nRounds) => { 18 | if (typeof seed === "undefined") seed = SEED; 19 | if (typeof nRounds === "undefined") nRounds = NROUNDS; 20 | const cts = new Array(nRounds); 21 | let c = Web3Utils.keccak256(SEED); 22 | for (let i=1; i{ 37 | let xL = bigInt(_xL_in); 38 | let xR = bigInt(_xR_in); 39 | const k = bigInt(_k); 40 | for (let i=0; i { 58 | if (typeof(numOutputs) === "undefined") { 59 | numOutputs = 1; 60 | } 61 | if (typeof(key) === "undefined") { 62 | key = F.zero; 63 | } 64 | 65 | let R = F.zero; 66 | let C = F.zero; 67 | 68 | for (let i=0; i F.affine(x)); 85 | } 86 | }; 87 | -------------------------------------------------------------------------------- /circomlib/src/mimcsponge_printconstants.js: -------------------------------------------------------------------------------- 1 | const mimcsponge = require("./mimcsponge.js"); 2 | 3 | const nRounds = 220; 4 | let S = "[\n"; 5 | const cts = mimcsponge.getConstants(); 6 | for (let i=0; i { 36 | if (typeof seed === "undefined") seed = SEED; 37 | if (typeof nRounds === "undefined") nRounds = NROUNDSF + NROUNDSP; 38 | if (typeof t === "undefined") t = T; 39 | let nonce = "0000"; 40 | let cmatrix = getPseudoRandom(seed+"_matrix_"+nonce, t*2); 41 | while (!allDifferent(cmatrix)) { 42 | nonce = (Number(nonce)+1)+""; 43 | while(nonce.length<4) nonce = "0"+nonce; 44 | cmatrix = getPseudoRandom(seed+"_matrix_"+nonce, t*2); 45 | } 46 | 47 | const M = new Array(t); 48 | for (let i=0; i { 58 | if (typeof seed === "undefined") seed = SEED; 59 | if (typeof nRounds === "undefined") nRounds = NROUNDSF + NROUNDSP; 60 | if (typeof t === "undefined") t = T; 61 | const cts = getPseudoRandom(seed+"_constants", nRounds); 62 | return cts; 63 | }; 64 | 65 | function ark(state, c) { 66 | for (let j=0; j { 87 | 88 | if (typeof seed === "undefined") seed = SEED; 89 | if (typeof nRoundsF === "undefined") nRoundsF = NROUNDSF; 90 | if (typeof nRoundsP === "undefined") nRoundsP = NROUNDSP; 91 | if (typeof t === "undefined") t = T; 92 | 93 | assert(nRoundsF % 2 == 0); 94 | const C = exports.getConstants(t, seed, nRoundsF + nRoundsP); 95 | const M = exports.getMatrix(t, seed, nRoundsF + nRoundsP); 96 | return function(inputs) { 97 | let state = []; 98 | assert(inputs.length <= t); 99 | assert(inputs.length > 0); 100 | for (let i=0; i= nRoundsF/2 + nRoundsP)) { 106 | for (let j=0; j { 29 | let circuit; 30 | before( async() => { 31 | const cirDef = await compiler(path.join(__dirname, "circuits", "aliascheck_test.circom")); 32 | 33 | circuit = new snarkjs.Circuit(cirDef); 34 | 35 | console.log("NConstrains: " + circuit.nConstraints); 36 | }); 37 | 38 | it("Satisfy the aliastest 0", async () => { 39 | const inp = getBits(bigInt.zero, 254); 40 | circuit.calculateWitness({in: inp}); 41 | }); 42 | 43 | it("Satisfy the aliastest 3", async () => { 44 | const inp = getBits(bigInt(3), 254); 45 | circuit.calculateWitness({in: inp}); 46 | }); 47 | 48 | it("Satisfy the aliastest q-1", async () => { 49 | const inp = getBits(q.sub(bigInt.one), 254); 50 | circuit.calculateWitness({in: inp}); 51 | }); 52 | 53 | it("Nhot not satisfy an input of q", async () => { 54 | const inp = getBits(q, 254); 55 | try { 56 | circuit.calculateWitness({in: inp}); 57 | assert(false); 58 | } catch(err) { 59 | assert.equal(err.message, "Constraint doesn't match: 1 != 0"); 60 | } 61 | }); 62 | 63 | it("Nhot not satisfy all ones", async () => { 64 | 65 | const inp = getBits(bigInt(1).shl(254).sub(bigInt(1)), 254); 66 | try { 67 | circuit.calculateWitness({in: inp}); 68 | assert(false); 69 | } catch(err) { 70 | assert.equal(err.message, "Constraint doesn't match: 1 != 0"); 71 | } 72 | }); 73 | 74 | }); 75 | -------------------------------------------------------------------------------- /circomlib/test/binsub.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const compiler = require("circom"); 5 | 6 | const assert = chai.assert; 7 | 8 | const bigInt = snarkjs.bigInt; 9 | 10 | function print(circuit, w, s) { 11 | console.log(s + ": " + w[circuit.getSignalIdx(s)]); 12 | } 13 | 14 | function checkSub(_a,_b, circuit) { 15 | let a=bigInt(_a); 16 | let b=bigInt(_b); 17 | if (a.lesser(bigInt.zero)) a = a.add(bigInt.one.shl(16)); 18 | if (b.lesser(bigInt.zero)) b = b.add(bigInt.one.shl(16)); 19 | const w = circuit.calculateWitness({a: a, b: b}); 20 | 21 | let res = a.sub(b); 22 | if (res.lesser(bigInt.zero)) res = res.add(bigInt.one.shl(16)); 23 | assert( w[circuit.getSignalIdx("main.out")].equals(bigInt(res)) ); 24 | } 25 | 26 | describe("BinSub test", () => { 27 | let circuit; 28 | before( async() => { 29 | const cirDef = await compiler(path.join(__dirname, "circuits", "binsub_test.circom")); 30 | 31 | circuit = new snarkjs.Circuit(cirDef); 32 | 33 | console.log("NConstrains BinSub: " + circuit.nConstraints); 34 | }); 35 | 36 | it("Should check variuos ege cases", async () => { 37 | checkSub(0,0, circuit); 38 | checkSub(1,0, circuit); 39 | checkSub(-1,0, circuit); 40 | checkSub(2,1, circuit); 41 | checkSub(2,2, circuit); 42 | checkSub(2,3, circuit); 43 | checkSub(2,-1, circuit); 44 | checkSub(2,-2, circuit); 45 | checkSub(2,-3, circuit); 46 | checkSub(-2,-3, circuit); 47 | checkSub(-2,-2, circuit); 48 | checkSub(-2,-1, circuit); 49 | checkSub(-2,0, circuit); 50 | checkSub(-2,1, circuit); 51 | checkSub(-2,2, circuit); 52 | checkSub(-2,3, circuit); 53 | }); 54 | 55 | 56 | }); 57 | -------------------------------------------------------------------------------- /circomlib/test/binsum.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const crypto = require("crypto"); 5 | 6 | const compiler = require("circom"); 7 | 8 | const assert = chai.assert; 9 | 10 | describe("Sum test", () => { 11 | it("Should create a constant circuit", async () => { 12 | 13 | const cirDef = await compiler(path.join(__dirname, "circuits", "constants_test.circom")); 14 | assert.equal(cirDef.nVars, 2); 15 | 16 | const circuit = new snarkjs.Circuit(cirDef); 17 | 18 | const witness = circuit.calculateWitness({ "in": "0xd807aa98" }); 19 | 20 | assert(witness[0].equals(snarkjs.bigInt(1))); 21 | assert(witness[1].equals(snarkjs.bigInt("0xd807aa98"))); 22 | }); 23 | it("Should create a sum circuit", async () => { 24 | 25 | const cirDef = await compiler(path.join(__dirname, "circuits", "sum_test.circom")); 26 | assert.equal(cirDef.nVars, 101); 27 | 28 | const circuit = new snarkjs.Circuit(cirDef); 29 | 30 | const witness = circuit.calculateWitness({ "a": "111", "b": "222" }); 31 | 32 | assert(witness[0].equals(snarkjs.bigInt(1))); 33 | assert(witness[1].equals(snarkjs.bigInt("333"))); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /circomlib/test/circuits/aliascheck_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/aliascheck.circom"; 2 | 3 | component main = AliasCheck() 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/babyadd_tester.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/babyjub.circom"; 2 | 3 | component main = BabyAdd(); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/babycheck_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/babyjub.circom"; 2 | 3 | component main = BabyCheck(); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/babypbk_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/babyjub.circom"; 2 | 3 | component main = BabyPbk(); -------------------------------------------------------------------------------- /circomlib/test/circuits/binsub_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/bitify.circom" 2 | include "../../circuits/binsub.circom" 3 | 4 | template A() { 5 | signal private input a; 6 | signal input b; 7 | signal output out; 8 | 9 | component n2ba = Num2Bits(16); 10 | component n2bb = Num2Bits(16); 11 | component sub = BinSub(16); 12 | component b2n = Bits2Num(16); 13 | 14 | n2ba.in <== a; 15 | n2bb.in <== b; 16 | 17 | for (var i=0; i<16; i++) { 18 | sub.in[0][i] <== n2ba.out[i]; 19 | sub.in[1][i] <== n2bb.out[i]; 20 | b2n.in[i] <== sub.out[i]; 21 | } 22 | 23 | out <== b2n.out; 24 | } 25 | 26 | component main = A(); 27 | -------------------------------------------------------------------------------- /circomlib/test/circuits/constants_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/sha256/constants.circom" 2 | 3 | template A() { 4 | signal input in; 5 | component h0; 6 | h0 = K(8); 7 | 8 | var lc = 0; 9 | var e = 1; 10 | for (var i=0; i<32; i++) { 11 | lc = lc + e*h0.out[i]; 12 | e *= 2; 13 | } 14 | 15 | lc === in; 16 | } 17 | 18 | component main = A(); 19 | -------------------------------------------------------------------------------- /circomlib/test/circuits/eddsa_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/eddsa.circom"; 2 | 3 | component main = EdDSAVerifier(80); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/eddsamimc_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/eddsamimc.circom"; 2 | 3 | component main = EdDSAMiMCVerifier(); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/eddsaposeidon_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/eddsaposeidon.circom"; 2 | 3 | component main = EdDSAPoseidonVerifier(); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/edwards2montgomery.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/montgomery.circom"; 2 | 3 | component main = Edwards2Montgomery(); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/escalarmul_min_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/escalarmul.circom"; 2 | 3 | 4 | template Main() { 5 | signal input in[256]; 6 | signal output out[2]; 7 | 8 | var i; 9 | 10 | var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 11 | 16950150798460657717958625567821834550301663161624707787222815936182638968203] 12 | 13 | component escalarMul = EscalarMul(256, base); 14 | 15 | escalarMul.inp[0] <== 0; 16 | escalarMul.inp[1] <== 1; 17 | 18 | for (i=0; i<256; i++) { 19 | in[i] ==> escalarMul.in[i]; 20 | } 21 | 22 | escalarMul.out[0] ==> out[0]; 23 | escalarMul.out[1] ==> out[1]; 24 | } 25 | 26 | component main = Main(); 27 | -------------------------------------------------------------------------------- /circomlib/test/circuits/escalarmul_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/escalarmul.circom"; 2 | include "../../circuits/bitify.circom"; 3 | 4 | 5 | template Main() { 6 | signal input in; 7 | signal output out[2]; 8 | 9 | var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 10 | 16950150798460657717958625567821834550301663161624707787222815936182638968203] 11 | 12 | 13 | component n2b = Num2Bits(253); 14 | component escalarMul = EscalarMul(253, base); 15 | 16 | escalarMul.inp[0] <== 0; 17 | escalarMul.inp[1] <== 1; 18 | 19 | var i; 20 | 21 | in ==> n2b.in; 22 | 23 | for (i=0; i<253; i++) { 24 | n2b.out[i] ==> escalarMul.in[i]; 25 | } 26 | 27 | escalarMul.out[0] ==> out[0]; 28 | escalarMul.out[1] ==> out[1]; 29 | } 30 | 31 | component main = Main(); 32 | -------------------------------------------------------------------------------- /circomlib/test/circuits/escalarmul_test_min.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/escalarmul.circom"; 2 | 3 | 4 | template Main() { 5 | signal input in[256]; 6 | signal output out[2]; 7 | 8 | var i; 9 | 10 | var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 11 | 16950150798460657717958625567821834550301663161624707787222815936182638968203] 12 | 13 | component escalarMul = EscalarMul(256, base); 14 | 15 | escalarMul.inp[0] <== 0; 16 | escalarMul.inp[1] <== 1; 17 | 18 | for (i=0; i<256; i++) { 19 | in[i] ==> escalarMul.in[i]; 20 | } 21 | 22 | escalarMul.out[0] ==> out[0]; 23 | escalarMul.out[1] ==> out[1]; 24 | } 25 | 26 | component main = Main(); 27 | -------------------------------------------------------------------------------- /circomlib/test/circuits/escalarmulany_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/escalarmulany.circom"; 2 | include "../../circuits/bitify.circom"; 3 | 4 | template Main() { 5 | signal input e; 6 | signal input p[2]; 7 | signal output out[2]; 8 | 9 | component n2b = Num2Bits(253); 10 | component escalarMulAny = EscalarMulAny(253); 11 | 12 | escalarMulAny.p[0] <== p[0]; 13 | escalarMulAny.p[1] <== p[1]; 14 | 15 | var i; 16 | 17 | e ==> n2b.in; 18 | 19 | for (i=0; i<253; i++) { 20 | n2b.out[i] ==> escalarMulAny.e[i]; 21 | } 22 | 23 | escalarMulAny.out[0] ==> out[0]; 24 | escalarMulAny.out[1] ==> out[1]; 25 | } 26 | 27 | component main = Main(); 28 | 29 | -------------------------------------------------------------------------------- /circomlib/test/circuits/escalarmulfix_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/escalarmulfix.circom"; 2 | include "../../circuits/bitify.circom"; 3 | 4 | 5 | template Main() { 6 | signal input e; 7 | signal output out[2]; 8 | 9 | var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 10 | 16950150798460657717958625567821834550301663161624707787222815936182638968203] 11 | 12 | 13 | component n2b = Num2Bits(253); 14 | component escalarMul = EscalarMulFix(253, base); 15 | 16 | var i; 17 | 18 | e ==> n2b.in; 19 | 20 | for (i=0; i<253; i++) { 21 | n2b.out[i] ==> escalarMul.e[i]; 22 | } 23 | 24 | escalarMul.out[0] ==> out[0]; 25 | escalarMul.out[1] ==> out[1]; 26 | } 27 | 28 | component main = Main(); 29 | 30 | -------------------------------------------------------------------------------- /circomlib/test/circuits/escalarmulw4table.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/escalarmulw4table.circom"; 2 | 3 | var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 4 | 16950150798460657717958625567821834550301663161624707787222815936182638968203] 5 | 6 | component main = EscalarMulW4Table(base, 0); 7 | -------------------------------------------------------------------------------- /circomlib/test/circuits/escalarmulw4table_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/escalarmulw4table.circom"; 2 | 3 | 4 | template Main() { 5 | signal input in; 6 | signal output out[16][2]; 7 | var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 8 | 16950150798460657717958625567821834550301663161624707787222815936182638968203]; 9 | 10 | component escalarMul = EscalarMulW4Table(base, 0); 11 | for (var i=0; i<16; i++) { 12 | out[i][0] <== escalarMul.out[i][0]*in; 13 | out[i][1] <== escalarMul.out[i][1]*in; 14 | } 15 | } 16 | 17 | component main = Main(); 18 | -------------------------------------------------------------------------------- /circomlib/test/circuits/escalarmulw4table_test3.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/escalarmulw4table.circom"; 2 | 3 | 4 | template Main() { 5 | signal input in; 6 | signal output out[16][2]; 7 | var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 8 | 16950150798460657717958625567821834550301663161624707787222815936182638968203]; 9 | 10 | component escalarMul = EscalarMulW4Table(base, 3); 11 | for (var i=0; i<16; i++) { 12 | out[i][0] <== escalarMul.out[i][0]*in; 13 | out[i][1] <== escalarMul.out[i][1]*in; 14 | } 15 | } 16 | 17 | component main = Main(); 18 | -------------------------------------------------------------------------------- /circomlib/test/circuits/greatereqthan.circom: -------------------------------------------------------------------------------- 1 | 2 | include "../../circuits/comparators.circom"; 3 | 4 | component main = GreaterEqThan(32); 5 | -------------------------------------------------------------------------------- /circomlib/test/circuits/greaterthan.circom: -------------------------------------------------------------------------------- 1 | 2 | include "../../circuits/comparators.circom"; 3 | 4 | component main = GreaterThan(32); 5 | -------------------------------------------------------------------------------- /circomlib/test/circuits/isequal.circom: -------------------------------------------------------------------------------- 1 | 2 | include "../../circuits/comparators.circom"; 3 | 4 | component main = IsEqual(); 5 | -------------------------------------------------------------------------------- /circomlib/test/circuits/iszero.circom: -------------------------------------------------------------------------------- 1 | 2 | 3 | include "../../circuits/comparators.circom"; 4 | 5 | component main = IsZero(); 6 | -------------------------------------------------------------------------------- /circomlib/test/circuits/lesseqthan.circom: -------------------------------------------------------------------------------- 1 | 2 | include "../../circuits/comparators.circom"; 3 | 4 | component main = LessEqThan(32); 5 | -------------------------------------------------------------------------------- /circomlib/test/circuits/lessthan.circom: -------------------------------------------------------------------------------- 1 | 2 | include "../../circuits/comparators.circom"; 3 | 4 | component main = LessThan(32); 5 | -------------------------------------------------------------------------------- /circomlib/test/circuits/mimc_sponge_hash_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/mimcsponge.circom" 2 | 3 | component main = MiMCSponge(2, 220, 3); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/mimc_sponge_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/mimcsponge.circom" 2 | 3 | component main = MiMCFeistel(220); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/mimc_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/mimc.circom" 2 | 3 | component main = MiMC7(91); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/montgomery2edwards.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/montgomery.circom"; 2 | 3 | component main = Montgomery2Edwards(); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/montgomeryadd.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/montgomery.circom"; 2 | 3 | component main = MontgomeryAdd(); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/montgomerydouble.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/montgomery.circom"; 2 | 3 | component main = MontgomeryDouble(); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/mux1_1.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/mux1.circom"; 2 | include "../../circuits/bitify.circom"; 3 | 4 | 5 | template Constants() { 6 | var i; 7 | signal output out[2]; 8 | 9 | out[0] <== 37; 10 | out[1] <== 47; 11 | } 12 | 13 | template Main() { 14 | var i; 15 | signal private input selector; 16 | signal output out; 17 | 18 | component mux = Mux1(); 19 | component n2b = Num2Bits(1); 20 | component cst = Constants(); 21 | 22 | selector ==> n2b.in; 23 | n2b.out[0] ==> mux.s; 24 | for (i=0; i<2; i++) { 25 | cst.out[i] ==> mux.c[i]; 26 | } 27 | 28 | mux.out ==> out; 29 | } 30 | 31 | component main = Main(); 32 | -------------------------------------------------------------------------------- /circomlib/test/circuits/mux2_1.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/mux2.circom"; 2 | include "../../circuits/bitify.circom"; 3 | 4 | 5 | template Constants() { 6 | var i; 7 | signal output out[4]; 8 | 9 | out[0] <== 37; 10 | out[1] <== 47; 11 | out[2] <== 53; 12 | out[3] <== 71; 13 | } 14 | 15 | template Main() { 16 | var i; 17 | signal private input selector; 18 | signal output out; 19 | 20 | component mux = Mux2(); 21 | component n2b = Num2Bits(2); 22 | component cst = Constants(); 23 | 24 | selector ==> n2b.in; 25 | for (i=0; i<2; i++) { 26 | n2b.out[i] ==> mux.s[i]; 27 | } 28 | for (i=0; i<4; i++) { 29 | cst.out[i] ==> mux.c[i]; 30 | } 31 | 32 | mux.out ==> out; 33 | } 34 | 35 | component main = Main(); 36 | -------------------------------------------------------------------------------- /circomlib/test/circuits/mux3_1.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/mux3.circom"; 2 | include "../../circuits/bitify.circom"; 3 | 4 | 5 | template Constants() { 6 | var i; 7 | signal output out[8]; 8 | 9 | out[0] <== 37; 10 | out[1] <== 47; 11 | out[2] <== 53; 12 | out[3] <== 71; 13 | out[4] <== 89; 14 | out[5] <== 107; 15 | out[6] <== 163; 16 | out[7] <== 191; 17 | } 18 | 19 | template Main() { 20 | var i; 21 | signal private input selector; 22 | signal output out; 23 | 24 | component mux = Mux3(); 25 | component n2b = Num2Bits(3); 26 | component cst = Constants(); 27 | 28 | selector ==> n2b.in; 29 | for (i=0; i<3; i++) { 30 | n2b.out[i] ==> mux.s[i]; 31 | } 32 | for (i=0; i<8; i++) { 33 | cst.out[i] ==> mux.c[i]; 34 | } 35 | 36 | mux.out ==> out; 37 | } 38 | 39 | component main = Main(); 40 | -------------------------------------------------------------------------------- /circomlib/test/circuits/mux4_1.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/mux4.circom"; 2 | include "../../circuits/bitify.circom"; 3 | 4 | 5 | template Constants() { 6 | var i; 7 | signal output out[16]; 8 | 9 | out[0] <== 123; 10 | out[1] <== 456; 11 | out[2] <== 789; 12 | out[3] <== 012; 13 | out[4] <== 111; 14 | out[5] <== 222; 15 | out[6] <== 333; 16 | out[7] <== 4546; 17 | out[8] <== 134523; 18 | out[9] <== 44356; 19 | out[10] <== 15623; 20 | out[11] <== 4566; 21 | out[12] <== 1223; 22 | out[13] <== 4546; 23 | out[14] <== 4256; 24 | out[15] <== 4456; 25 | 26 | /* 27 | for (i=0;i<16; i++) { 28 | out[i] <== i*2+100; 29 | } 30 | */ 31 | 32 | } 33 | 34 | template Main() { 35 | var i; 36 | signal private input selector; 37 | signal output out; 38 | 39 | component mux = Mux4(); 40 | component n2b = Num2Bits(4); 41 | component cst = Constants(); 42 | 43 | selector ==> n2b.in; 44 | for (i=0; i<4; i++) { 45 | n2b.out[i] ==> mux.s[i]; 46 | } 47 | for (i=0; i<16; i++) { 48 | cst.out[i] ==> mux.c[i]; 49 | } 50 | 51 | mux.out ==> out; 52 | } 53 | 54 | component main = Main(); 55 | -------------------------------------------------------------------------------- /circomlib/test/circuits/pedersen2_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/pedersen.circom"; 2 | include "../../circuits/bitify.circom"; 3 | 4 | 5 | template Main() { 6 | signal input in; 7 | signal output out[2]; 8 | 9 | component pedersen = Pedersen(256); 10 | 11 | component n2b; 12 | n2b = Num2Bits(253); 13 | 14 | var i; 15 | 16 | in ==> n2b.in; 17 | 18 | for (i=0; i<253; i++) { 19 | pedersen.in[i] <== n2b.out[i]; 20 | } 21 | 22 | for (i=253; i<256; i++) { 23 | pedersen.in[i] <== 0; 24 | } 25 | 26 | pedersen.out[0] ==> out[0]; 27 | pedersen.out[1] ==> out[1]; 28 | } 29 | 30 | component main = Main(); 31 | 32 | 33 | -------------------------------------------------------------------------------- /circomlib/test/circuits/pedersen_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/pedersen_old.circom"; 2 | include "../../circuits/bitify.circom"; 3 | 4 | 5 | template Main() { 6 | signal input in[2]; 7 | signal output out[2]; 8 | 9 | component pedersen = Pedersen(250*2); 10 | 11 | component n2b[2]; 12 | n2b[0] = Num2Bits(250); 13 | n2b[1] = Num2Bits(250); 14 | 15 | var i; 16 | 17 | in[0] ==> n2b[0].in; 18 | in[1] ==> n2b[1].in; 19 | 20 | for (i=0; i<250; i++) { 21 | n2b[0].out[i] ==> pedersen.in[i]; 22 | n2b[1].out[i] ==> pedersen.in[250+i]; 23 | } 24 | 25 | pedersen.out[0] ==> out[0]; 26 | pedersen.out[1] ==> out[1]; 27 | } 28 | 29 | component main = Main(); 30 | -------------------------------------------------------------------------------- /circomlib/test/circuits/pointbits_loopback.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/pointbits.circom"; 2 | 3 | 4 | template Main() { 5 | signal input in[2]; 6 | 7 | var i 8 | 9 | component p2b = Point2Bits_Strict(); 10 | component b2p = Bits2Point_Strict(); 11 | 12 | p2b.in[0] <== in[0]; 13 | p2b.in[1] <== in[1]; 14 | 15 | for (i=0; i<256; i++) { 16 | b2p.in[i] <== p2b.out[i]; 17 | } 18 | 19 | b2p.out[0] === in[0]; 20 | b2p.out[1] === in[1]; 21 | } 22 | 23 | component main = Main(); 24 | -------------------------------------------------------------------------------- /circomlib/test/circuits/poseidon_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/poseidon.circom" 2 | 3 | component main = Poseidon(2, 6, 8, 57); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/sha256_2_test.circom: -------------------------------------------------------------------------------- 1 | include "../circomlib/circuits/sha256/sha256_2.circom"; 2 | 3 | template Main() { 4 | signal private input a; 5 | signal private input b; 6 | signal output out; 7 | 8 | component sha256_2 = Sha256_2(); 9 | 10 | sha256_2.a <== a; 11 | sha256_2.b <== b; 12 | out <== sha256_2.out; 13 | } 14 | 15 | component main = Main(); 16 | -------------------------------------------------------------------------------- /circomlib/test/circuits/sha256_test448.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/sha256/sha256.circom"; 2 | 3 | component main = Sha256(448); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/sha256_test512.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/sha256/sha256.circom"; 2 | 3 | component main = Sha256(512); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/sign_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/sign.circom"; 2 | 3 | component main = Sign(); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/smtprocessor10_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/smt/smtprocessor.circom"; 2 | 3 | component main = SMTProcessor(10); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/smtverifier10_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/smt/smtverifier.circom"; 2 | 3 | component main = SMTVerifier(10); 4 | -------------------------------------------------------------------------------- /circomlib/test/circuits/sum_test.circom: -------------------------------------------------------------------------------- 1 | include "../../circuits/bitify.circom" 2 | include "../../circuits/binsum.circom" 3 | 4 | template A() { 5 | signal private input a; 6 | signal input b; 7 | signal output out; 8 | 9 | component n2ba = Num2Bits(32); 10 | component n2bb = Num2Bits(32); 11 | component sum = BinSum(32,2); 12 | component b2n = Bits2Num(32); 13 | 14 | n2ba.in <== a; 15 | n2bb.in <== b; 16 | 17 | for (var i=0; i<32; i++) { 18 | sum.in[0][i] <== n2ba.out[i]; 19 | sum.in[1][i] <== n2bb.out[i]; 20 | b2n.in[i] <== sum.out[i]; 21 | } 22 | 23 | out <== b2n.out; 24 | } 25 | 26 | component main = A(); 27 | -------------------------------------------------------------------------------- /circomlib/test/eddsa.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const compiler = require("circom"); 5 | // const crypto = require("crypto"); 6 | 7 | const eddsa = require("../src/eddsa.js"); 8 | const babyJub = require("../src/babyjub.js"); 9 | 10 | const assert = chai.assert; 11 | 12 | const bigInt = snarkjs.bigInt; 13 | 14 | function print(circuit, w, s) { 15 | console.log(s + ": " + w[circuit.getSignalIdx(s)]); 16 | } 17 | 18 | function buffer2bits(buff) { 19 | const res = []; 20 | for (let i=0; i>j)&1) { 23 | res.push(bigInt.one); 24 | } else { 25 | res.push(bigInt.zero); 26 | } 27 | } 28 | } 29 | return res; 30 | } 31 | 32 | 33 | describe("EdDSA test", function () { 34 | let circuit; 35 | 36 | this.timeout(100000); 37 | 38 | before( async () => { 39 | const cirDef = await compiler(path.join(__dirname, "circuits", "eddsa_test.circom")); 40 | 41 | circuit = new snarkjs.Circuit(cirDef); 42 | 43 | console.log("NConstrains EdDSA: " + circuit.nConstraints); 44 | }); 45 | 46 | it("Sign a single 10 bytes from 0 to 9", async () => { 47 | const msg = Buffer.from("00010203040506070809", "hex"); 48 | 49 | // const prvKey = crypto.randomBytes(32); 50 | 51 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 52 | 53 | const pubKey = eddsa.prv2pub(prvKey); 54 | 55 | const pPubKey = babyJub.packPoint(pubKey); 56 | 57 | const signature = eddsa.sign(prvKey, msg); 58 | 59 | const pSignature = eddsa.packSignature(signature); 60 | const uSignature = eddsa.unpackSignature(pSignature); 61 | 62 | assert(eddsa.verify(msg, uSignature, pubKey)); 63 | 64 | const msgBits = buffer2bits(msg); 65 | const r8Bits = buffer2bits(pSignature.slice(0, 32)); 66 | const sBits = buffer2bits(pSignature.slice(32, 64)); 67 | const aBits = buffer2bits(pPubKey); 68 | 69 | const w = circuit.calculateWitness({A: aBits, R8: r8Bits, S: sBits, msg: msgBits}); 70 | 71 | assert(circuit.checkWitness(w)); 72 | 73 | }); 74 | }); 75 | -------------------------------------------------------------------------------- /circomlib/test/eddsa_js.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const snarkjs = require("snarkjs"); 3 | 4 | const eddsa = require("../src/eddsa.js"); 5 | const babyJub = require("../src/babyjub.js"); 6 | 7 | const assert = chai.assert; 8 | 9 | const bigInt = snarkjs.bigInt; 10 | 11 | describe("EdDSA js test", function () { 12 | 13 | this.timeout(100000); 14 | 15 | it("Sign (using Mimc7) a single 10 bytes from 0 to 9", () => { 16 | const msgBuf = Buffer.from("00010203040506070809", "hex"); 17 | const msg = bigInt.leBuff2int(msgBuf); 18 | 19 | // const prvKey = crypto.randomBytes(32); 20 | 21 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 22 | 23 | const pubKey = eddsa.prv2pub(prvKey); 24 | 25 | assert.equal(pubKey[0].toString(), 26 | "13277427435165878497778222415993513565335242147425444199013288855685581939618"); 27 | assert.equal(pubKey[1].toString(), 28 | "13622229784656158136036771217484571176836296686641868549125388198837476602820"); 29 | 30 | const pPubKey = babyJub.packPoint(pubKey); 31 | 32 | const signature = eddsa.signMiMC(prvKey, msg); 33 | assert.equal(signature.R8[0].toString(), 34 | "11384336176656855268977457483345535180380036354188103142384839473266348197733"); 35 | assert.equal(signature.R8[1].toString(), 36 | "15383486972088797283337779941324724402501462225528836549661220478783371668959"); 37 | assert.equal(signature.S.toString(), 38 | "2523202440825208709475937830811065542425109372212752003460238913256192595070"); 39 | 40 | const pSignature = eddsa.packSignature(signature); 41 | assert.equal(pSignature.toString("hex"), ""+ 42 | "dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+ 43 | "7ed40dab29bf993c928e789d007387998901a24913d44fddb64b1f21fc149405"); 44 | 45 | const uSignature = eddsa.unpackSignature(pSignature); 46 | assert(eddsa.verifyMiMC(msg, uSignature, pubKey)); 47 | 48 | }); 49 | 50 | it("Sign (using Poseidon) a single 10 bytes from 0 to 9", () => { 51 | const msgBuf = Buffer.from("00010203040506070809", "hex"); 52 | const msg = bigInt.leBuff2int(msgBuf); 53 | 54 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 55 | 56 | const pubKey = eddsa.prv2pub(prvKey); 57 | 58 | assert.equal(pubKey[0].toString(), 59 | "13277427435165878497778222415993513565335242147425444199013288855685581939618"); 60 | assert.equal(pubKey[1].toString(), 61 | "13622229784656158136036771217484571176836296686641868549125388198837476602820"); 62 | 63 | const pPubKey = babyJub.packPoint(pubKey); 64 | 65 | const signature = eddsa.signPoseidon(prvKey, msg); 66 | assert.equal(signature.R8[0].toString(), 67 | "11384336176656855268977457483345535180380036354188103142384839473266348197733"); 68 | assert.equal(signature.R8[1].toString(), 69 | "15383486972088797283337779941324724402501462225528836549661220478783371668959"); 70 | assert.equal(signature.S.toString(), 71 | "248298168863866362217836334079793350221620631973732197668910946177382043688"); 72 | 73 | const pSignature = eddsa.packSignature(signature); 74 | assert.equal(pSignature.toString("hex"), ""+ 75 | "dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+ 76 | "28506bce274aa1b3f7e7c2fd7e4fe09bff8f9aa37a42def7994e98f322888c00"); 77 | 78 | const uSignature = eddsa.unpackSignature(pSignature); 79 | assert(eddsa.verifyPoseidon(msg, uSignature, pubKey)); 80 | 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /circomlib/test/eddsamimc.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const compiler = require("circom"); 5 | 6 | const eddsa = require("../src/eddsa.js"); 7 | 8 | const assert = chai.assert; 9 | 10 | const bigInt = snarkjs.bigInt; 11 | 12 | describe("EdDSA MiMC test", function () { 13 | let circuit; 14 | 15 | this.timeout(100000); 16 | 17 | before( async () => { 18 | const cirDef = await compiler(path.join(__dirname, "circuits", "eddsamimc_test.circom")); 19 | 20 | circuit = new snarkjs.Circuit(cirDef); 21 | 22 | console.log("NConstrains EdDSA MiMC: " + circuit.nConstraints); 23 | }); 24 | 25 | it("Sign a single number", async () => { 26 | const msg = bigInt(1234); 27 | 28 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 29 | 30 | const pubKey = eddsa.prv2pub(prvKey); 31 | 32 | const signature = eddsa.signMiMC(prvKey, msg); 33 | 34 | assert(eddsa.verifyMiMC(msg, signature, pubKey)); 35 | 36 | const w = circuit.calculateWitness({ 37 | enabled: 1, 38 | Ax: pubKey[0], 39 | Ay: pubKey[1], 40 | R8x: signature.R8[0], 41 | R8y: signature.R8[1], 42 | S: signature.S, 43 | M: msg}); 44 | 45 | assert(circuit.checkWitness(w)); 46 | }); 47 | 48 | it("Detect Invalid signature", async () => { 49 | const msg = bigInt(1234); 50 | 51 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 52 | 53 | const pubKey = eddsa.prv2pub(prvKey); 54 | 55 | 56 | const signature = eddsa.signMiMC(prvKey, msg); 57 | 58 | assert(eddsa.verifyMiMC(msg, signature, pubKey)); 59 | try { 60 | const w = circuit.calculateWitness({ 61 | enabled: 1, 62 | Ax: pubKey[0], 63 | Ay: pubKey[1], 64 | R8x: signature.R8[0].add(bigInt(1)), 65 | R8y: signature.R8[1], 66 | S: signature.S, 67 | M: msg}); 68 | assert(false); 69 | } catch(err) { 70 | assert.equal(err.message, "Constraint doesn't match: 1 != 0"); 71 | } 72 | }); 73 | 74 | 75 | it("Test a dissabled circuit with a bad signature", async () => { 76 | const msg = bigInt(1234); 77 | 78 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 79 | 80 | const pubKey = eddsa.prv2pub(prvKey); 81 | 82 | 83 | const signature = eddsa.signMiMC(prvKey, msg); 84 | 85 | assert(eddsa.verifyMiMC(msg, signature, pubKey)); 86 | 87 | const w = circuit.calculateWitness({ 88 | enabled: 0, 89 | Ax: pubKey[0], 90 | Ay: pubKey[1], 91 | R8x: signature.R8[0].add(bigInt(1)), 92 | R8y: signature.R8[1], 93 | S: signature.S, 94 | M: msg}); 95 | 96 | assert(circuit.checkWitness(w)); 97 | }); 98 | }); 99 | -------------------------------------------------------------------------------- /circomlib/test/eddsaposeidon.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const compiler = require("circom"); 5 | 6 | const eddsa = require("../src/eddsa.js"); 7 | 8 | const assert = chai.assert; 9 | 10 | const bigInt = snarkjs.bigInt; 11 | 12 | describe("EdDSA Poseidon test", function () { 13 | let circuit; 14 | 15 | this.timeout(100000); 16 | 17 | before( async () => { 18 | const cirDef = await compiler(path.join(__dirname, "circuits", "eddsaposeidon_test.circom")); 19 | 20 | circuit = new snarkjs.Circuit(cirDef); 21 | 22 | console.log("NConstrains EdDSA Poseidon: " + circuit.nConstraints); 23 | }); 24 | 25 | it("Sign a single number", async () => { 26 | const msg = bigInt(1234); 27 | 28 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 29 | 30 | const pubKey = eddsa.prv2pub(prvKey); 31 | 32 | const signature = eddsa.signPoseidon(prvKey, msg); 33 | 34 | assert(eddsa.verifyPoseidon(msg, signature, pubKey)); 35 | 36 | const w = circuit.calculateWitness({ 37 | enabled: 1, 38 | Ax: pubKey[0], 39 | Ay: pubKey[1], 40 | R8x: signature.R8[0], 41 | R8y: signature.R8[1], 42 | S: signature.S, 43 | M: msg}); 44 | 45 | assert(circuit.checkWitness(w)); 46 | }); 47 | 48 | it("Detect Invalid signature", async () => { 49 | const msg = bigInt(1234); 50 | 51 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 52 | 53 | const pubKey = eddsa.prv2pub(prvKey); 54 | 55 | 56 | const signature = eddsa.signPoseidon(prvKey, msg); 57 | 58 | assert(eddsa.verifyPoseidon(msg, signature, pubKey)); 59 | try { 60 | circuit.calculateWitness({ 61 | enabled: 1, 62 | Ax: pubKey[0], 63 | Ay: pubKey[1], 64 | R8x: signature.R8[0].add(bigInt(1)), 65 | R8y: signature.R8[1], 66 | S: signature.S, 67 | M: msg}); 68 | assert(false); 69 | } catch(err) { 70 | assert.equal(err.message, "Constraint doesn't match: 1 != 0"); 71 | } 72 | }); 73 | 74 | 75 | it("Test a dissabled circuit with a bad signature", async () => { 76 | const msg = bigInt(1234); 77 | 78 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 79 | 80 | const pubKey = eddsa.prv2pub(prvKey); 81 | 82 | 83 | const signature = eddsa.signPoseidon(prvKey, msg); 84 | 85 | assert(eddsa.verifyPoseidon(msg, signature, pubKey)); 86 | 87 | const w = circuit.calculateWitness({ 88 | enabled: 0, 89 | Ax: pubKey[0], 90 | Ay: pubKey[1], 91 | R8x: signature.R8[0].add(bigInt(1)), 92 | R8y: signature.R8[1], 93 | S: signature.S, 94 | M: msg}); 95 | 96 | assert(circuit.checkWitness(w)); 97 | }); 98 | }); 99 | -------------------------------------------------------------------------------- /circomlib/test/escalarmulany.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const compiler = require("circom"); 5 | 6 | const assert = chai.assert; 7 | 8 | const bigInt = snarkjs.bigInt; 9 | 10 | 11 | function print(circuit, w, s) { 12 | console.log(s + ": " + w[circuit.getSignalIdx(s)]); 13 | } 14 | 15 | describe("Escalarmul test", function () { 16 | let circuitEMulAny; 17 | 18 | this.timeout(100000); 19 | 20 | let g = [ 21 | snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), 22 | snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203") 23 | ]; 24 | 25 | before( async() => { 26 | const cirDefEMulAny = await compiler(path.join(__dirname, "circuits", "escalarmulany_test.circom")); 27 | circuitEMulAny = new snarkjs.Circuit(cirDefEMulAny); 28 | console.log("NConstrains Escalarmul any: " + circuitEMulAny.nConstraints); 29 | }); 30 | 31 | it("Should generate Same escalar mul", async () => { 32 | 33 | const w = circuitEMulAny.calculateWitness({"e": 1, "p": g}); 34 | 35 | assert(circuitEMulAny.checkWitness(w)); 36 | 37 | const xout = w[circuitEMulAny.getSignalIdx("main.out[0]")]; 38 | const yout = w[circuitEMulAny.getSignalIdx("main.out[1]")]; 39 | 40 | assert(xout.equals(g[0])); 41 | assert(yout.equals(g[1])); 42 | }); 43 | 44 | it("If multiply by order should return 0", async () => { 45 | 46 | const r = bigInt("2736030358979909402780800718157159386076813972158567259200215660948447373041"); 47 | const w = circuitEMulAny.calculateWitness({"e": r, "p": g}); 48 | 49 | assert(circuitEMulAny.checkWitness(w)); 50 | 51 | const xout = w[circuitEMulAny.getSignalIdx("main.out[0]")]; 52 | const yout = w[circuitEMulAny.getSignalIdx("main.out[1]")]; 53 | 54 | assert(xout.equals(bigInt.zero)); 55 | assert(yout.equals(bigInt.one)); 56 | }); 57 | 58 | }); 59 | 60 | -------------------------------------------------------------------------------- /circomlib/test/escalarmulfix.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const compiler = require("circom"); 5 | const babyjub = require("../src/babyjub"); 6 | 7 | const assert = chai.assert; 8 | 9 | const bigInt = snarkjs.bigInt; 10 | 11 | 12 | function print(circuit, w, s) { 13 | console.log(s + ": " + w[circuit.getSignalIdx(s)]); 14 | } 15 | 16 | describe("Escalarmul test", function () { 17 | let circuit; 18 | 19 | this.timeout(100000); 20 | 21 | before( async() => { 22 | const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulfix_test.circom")); 23 | circuit = new snarkjs.Circuit(cirDef); 24 | console.log("NConstrains Escalarmul fix: " + circuit.nConstraints); 25 | }); 26 | 27 | it("Should generate Same escalar mul", async () => { 28 | 29 | const w = circuit.calculateWitness({"e": 0}); 30 | 31 | assert(circuit.checkWitness(w)); 32 | 33 | const xout = w[circuit.getSignalIdx("main.out[0]")]; 34 | const yout = w[circuit.getSignalIdx("main.out[1]")]; 35 | 36 | assert(xout.equals(0)); 37 | assert(yout.equals(1)); 38 | }); 39 | 40 | it("Should generate Same escalar mul", async () => { 41 | 42 | const w = circuit.calculateWitness({"e": 1}); 43 | 44 | assert(circuit.checkWitness(w)); 45 | 46 | const xout = w[circuit.getSignalIdx("main.out[0]")]; 47 | const yout = w[circuit.getSignalIdx("main.out[1]")]; 48 | 49 | assert(xout.equals(babyjub.Base8[0])); 50 | assert(yout.equals(babyjub.Base8[1])); 51 | }); 52 | 53 | it("Should generate scalar mul of a specific constant", async () => { 54 | 55 | const s = bigInt("2351960337287830298912035165133676222414898052661454064215017316447594616519"); 56 | const base8 = [ 57 | bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), 58 | bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203") 59 | ]; 60 | 61 | const w = circuit.calculateWitness({"e": s}); 62 | 63 | assert(circuit.checkWitness(w)); 64 | 65 | const xout = w[circuit.getSignalIdx("main.out[0]")]; 66 | const yout = w[circuit.getSignalIdx("main.out[1]")]; 67 | 68 | const expectedRes = babyjub.mulPointEscalar(base8, s); 69 | 70 | assert(xout.equals(expectedRes[0])); 71 | assert(yout.equals(expectedRes[1])); 72 | }); 73 | 74 | it("Should generate scalar mul of the firsts 50 elements", async () => { 75 | 76 | const base8 = [ 77 | bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), 78 | bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203") 79 | ]; 80 | 81 | for (let i=0; i<50; i++) { 82 | const s = bigInt(i); 83 | 84 | const w = circuit.calculateWitness({"e": s}); 85 | 86 | assert(circuit.checkWitness(w)); 87 | 88 | const xout = w[circuit.getSignalIdx("main.out[0]")]; 89 | const yout = w[circuit.getSignalIdx("main.out[1]")]; 90 | 91 | const expectedRes = babyjub.mulPointEscalar(base8, s); 92 | 93 | assert(xout.equals(expectedRes[0])); 94 | assert(yout.equals(expectedRes[1])); 95 | } 96 | }); 97 | 98 | it("If multiply by order should return 0", async () => { 99 | 100 | const w = circuit.calculateWitness({"e": babyjub.subOrder }); 101 | 102 | assert(circuit.checkWitness(w)); 103 | 104 | const xout = w[circuit.getSignalIdx("main.out[0]")]; 105 | const yout = w[circuit.getSignalIdx("main.out[1]")]; 106 | 107 | assert(xout.equals(bigInt.zero)); 108 | assert(yout.equals(bigInt.one)); 109 | }); 110 | 111 | }); 112 | 113 | -------------------------------------------------------------------------------- /circomlib/test/helpers/printsignal.js: -------------------------------------------------------------------------------- 1 | 2 | const snarkjs = require("snarkjs"); 3 | 4 | const bigInt = snarkjs.bigInt; 5 | 6 | module.exports = function hexBits(cir, witness, sig, nBits) { 7 | let v = bigInt(0); 8 | for (let i=nBits-1; i>=0; i--) { 9 | v = v.shiftLeft(1); 10 | const name = sig+"["+i+"]"; 11 | const idx = cir.getSignalIdx(name); 12 | const vbit = bigInt(witness[idx].toString()); 13 | if (vbit.equals(bigInt(1))) { 14 | v = v.add(bigInt(1)); 15 | } else if (vbit.equals(bigInt(0))) { 16 | v; 17 | } else { 18 | console.log("Not Binary: "+name); 19 | } 20 | } 21 | return v.toString(16); 22 | }; 23 | -------------------------------------------------------------------------------- /circomlib/test/mimccircuit.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const compiler = require("circom"); 5 | 6 | const mimcjs = require("../src/mimc7.js"); 7 | 8 | const assert = chai.assert; 9 | 10 | describe("MiMC Circuit test", function () { 11 | let circuit; 12 | 13 | this.timeout(100000); 14 | 15 | before( async () => { 16 | const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_test.circom")); 17 | 18 | circuit = new snarkjs.Circuit(cirDef); 19 | 20 | console.log("MiMC constraints: " + circuit.nConstraints); 21 | }); 22 | 23 | it("Should check constrain", async () => { 24 | const w = circuit.calculateWitness({x_in: 1, k: 2}); 25 | 26 | const res = w[circuit.getSignalIdx("main.out")]; 27 | 28 | const res2 = mimcjs.hash(1,2,91); 29 | 30 | assert.equal(res.toString(), res2.toString()); 31 | 32 | assert(circuit.checkWitness(w)); 33 | 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /circomlib/test/mimccontract.js: -------------------------------------------------------------------------------- 1 | const ganache = require("ganache-cli"); 2 | const Web3 = require("web3"); 3 | const chai = require("chai"); 4 | const mimcGenContract = require("../src/mimc_gencontract.js"); 5 | const mimcjs = require("../src/mimc7.js"); 6 | 7 | 8 | const assert = chai.assert; 9 | const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); }; 10 | 11 | const SEED = "mimc"; 12 | 13 | describe("MiMC Smart contract test", function () { 14 | let testrpc; 15 | let web3; 16 | let mimc; 17 | let accounts; 18 | 19 | this.timeout(100000); 20 | 21 | before(async () => { 22 | web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"), null, { transactionConfirmationBlocks: 1 }); 23 | accounts = await web3.eth.getAccounts(); 24 | }); 25 | 26 | it("Should deploy the contract", async () => { 27 | const C = new web3.eth.Contract(mimcGenContract.abi); 28 | 29 | mimc = await C.deploy({ 30 | data: mimcGenContract.createCode(SEED, 91), 31 | arguments: [] 32 | }).send({ 33 | gas: 1500000, 34 | gasPrice: '30000000000000', 35 | from: accounts[0] 36 | }).on("error", (error) => { 37 | console.log("ERROR: "+error); 38 | }); 39 | 40 | console.log(mimc.address) 41 | }); 42 | 43 | it("Shold calculate the mimic correctly", async () => { 44 | const res = await mimc.methods.MiMCpe7(1,1).call(); 45 | const res2 = await mimcjs.hash(1,1,91); 46 | console.info(res.toString()) 47 | 48 | assert.equal(res.toString(), res2.toString()); 49 | }); 50 | }); 51 | 52 | -------------------------------------------------------------------------------- /circomlib/test/mimcspongecircuit.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const compiler = require("circom"); 5 | 6 | const mimcjs = require("../src/mimcsponge.js"); 7 | 8 | const assert = chai.assert; 9 | 10 | describe("MiMC Sponge Circuit test", function () { 11 | let circuit; 12 | 13 | this.timeout(100000); 14 | 15 | it("Should check permutation", async () => { 16 | const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_sponge_test.circom")); 17 | 18 | circuit = new snarkjs.Circuit(cirDef); 19 | 20 | console.log("MiMC Feistel constraints: " + circuit.nConstraints); 21 | 22 | const w = circuit.calculateWitness({xL_in: 1, xR_in: 2, k: 3}); 23 | 24 | const xLout = w[circuit.getSignalIdx("main.xL_out")]; 25 | const xRout = w[circuit.getSignalIdx("main.xR_out")]; 26 | 27 | const out2 = mimcjs.hash(1,2,3); 28 | 29 | assert.equal(xLout.toString(), out2.xL.toString()); 30 | assert.equal(xRout.toString(), out2.xR.toString()); 31 | 32 | assert(circuit.checkWitness(w)); 33 | 34 | }); 35 | 36 | it("Should check hash", async () => { 37 | const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_sponge_hash_test.circom")); 38 | 39 | circuit = new snarkjs.Circuit(cirDef); 40 | 41 | console.log("MiMC Sponge constraints: " + circuit.nConstraints); 42 | 43 | const w = circuit.calculateWitness({ins: [1, 2], k: 0}); 44 | 45 | const o1 = w[circuit.getSignalIdx("main.outs[0]")]; 46 | const o2 = w[circuit.getSignalIdx("main.outs[1]")]; 47 | const o3 = w[circuit.getSignalIdx("main.outs[2]")]; 48 | 49 | const out2 = mimcjs.multiHash([1,2], 0, 3); 50 | 51 | assert.equal(o1.toString(), out2[0].toString()); 52 | assert.equal(o2.toString(), out2[1].toString()); 53 | assert.equal(o3.toString(), out2[2].toString()); 54 | 55 | assert(circuit.checkWitness(w)); 56 | 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /circomlib/test/mimcspongecontract.js: -------------------------------------------------------------------------------- 1 | const ganache = require("ganache-cli"); 2 | const Web3 = require("web3"); 3 | const chai = require("chai"); 4 | const mimcGenContract = require("../src/mimcsponge_gencontract.js"); 5 | const mimcjs = require("../src/mimcsponge.js"); 6 | 7 | 8 | const assert = chai.assert; 9 | const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); }; 10 | 11 | const SEED = "mimcsponge"; 12 | 13 | describe("MiMC Sponge Smart contract test", () => { 14 | let testrpc; 15 | let web3; 16 | let mimc; 17 | let accounts; 18 | 19 | before(async () => { 20 | web3 = new Web3(ganache.provider(), null, { transactionConfirmationBlocks: 1 }); 21 | accounts = await web3.eth.getAccounts(); 22 | }); 23 | 24 | it("Should deploy the contract", async () => { 25 | const C = new web3.eth.Contract(mimcGenContract.abi); 26 | 27 | mimc = await C.deploy({ 28 | data: mimcGenContract.createCode(SEED, 220) 29 | }).send({ 30 | gas: 3500000, 31 | from: accounts[0] 32 | }); 33 | }); 34 | 35 | it("Shold calculate the mimc correctly", async () => { 36 | const res = await mimc.methods.MiMCSponge(1,2,3).call(); 37 | const res2 = await mimcjs.hash(1,2,3); 38 | 39 | assert.equal(res.xL.toString(), res2.xL.toString()); 40 | assert.equal(res.xR.toString(), res2.xR.toString()); 41 | }); 42 | }); 43 | 44 | -------------------------------------------------------------------------------- /circomlib/test/montgomery.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const compiler = require("circom"); 5 | const babyJub = require("../src/babyjub.js"); 6 | 7 | const assert = chai.assert; 8 | 9 | const bigInt = snarkjs.bigInt; 10 | 11 | describe("Montgomery test", function () { 12 | let circuitE2M; 13 | let circuitM2E; 14 | let circuitMAdd; 15 | let circuitMDouble; 16 | 17 | let g = [ 18 | snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), 19 | snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]; 20 | 21 | let mg, mg2, g2, g3, mg3; 22 | 23 | this.timeout(100000); 24 | before( async() => { 25 | const cirDefE2M = await compiler(path.join(__dirname, "circuits", "edwards2montgomery.circom")); 26 | circuitE2M = new snarkjs.Circuit(cirDefE2M); 27 | console.log("NConstrains Edwards -> Montgomery: " + circuitE2M.nConstraints); 28 | 29 | const cirDefM2E = await compiler(path.join(__dirname, "circuits", "montgomery2edwards.circom")); 30 | circuitM2E = new snarkjs.Circuit(cirDefM2E); 31 | console.log("NConstrains Montgomery -> Edwards: " + circuitM2E.nConstraints); 32 | 33 | const cirDefMAdd = await compiler(path.join(__dirname, "circuits", "montgomeryadd.circom")); 34 | circuitMAdd = new snarkjs.Circuit(cirDefMAdd); 35 | console.log("NConstrains Montgomery Add: " + circuitMAdd.nConstraints); 36 | 37 | const cirDefMDouble = await compiler(path.join(__dirname, "circuits", "montgomerydouble.circom")); 38 | circuitMDouble = new snarkjs.Circuit(cirDefMDouble); 39 | console.log("NConstrains Montgomery Double: " + circuitMDouble.nConstraints); 40 | }); 41 | it("Convert Edwards to Montgomery and back again", async () => { 42 | let w, xout, yout; 43 | 44 | w = circuitE2M.calculateWitness({ in: g}); 45 | 46 | xout = w[circuitE2M.getSignalIdx("main.out[0]")]; 47 | yout = w[circuitE2M.getSignalIdx("main.out[1]")]; 48 | 49 | mg = [xout, yout]; 50 | 51 | w = circuitM2E.calculateWitness({ in: [xout, yout]}); 52 | 53 | xout = w[circuitM2E.getSignalIdx("main.out[0]")]; 54 | yout = w[circuitM2E.getSignalIdx("main.out[1]")]; 55 | 56 | assert(xout.equals(g[0])); 57 | assert(yout.equals(g[1])); 58 | }); 59 | it("Should double a point", async () => { 60 | let w, xout, yout; 61 | 62 | g2 = babyJub.addPoint(g,g); 63 | 64 | w = circuitMDouble.calculateWitness({ in: mg}); 65 | 66 | xout = w[circuitE2M.getSignalIdx("main.out[0]")]; 67 | yout = w[circuitE2M.getSignalIdx("main.out[1]")]; 68 | 69 | mg2 = [xout, yout]; 70 | 71 | w = circuitM2E.calculateWitness({ in: mg2}); 72 | 73 | xout = w[circuitM2E.getSignalIdx("main.out[0]")]; 74 | yout = w[circuitM2E.getSignalIdx("main.out[1]")]; 75 | 76 | assert(xout.equals(g2[0])); 77 | assert(yout.equals(g2[1])); 78 | }); 79 | it("Should add a point", async () => { 80 | let w, xout, yout; 81 | 82 | g3 = babyJub.addPoint(g,g2); 83 | 84 | w = circuitMAdd.calculateWitness({ in1: mg, in2: mg2}); 85 | 86 | xout = w[circuitMAdd.getSignalIdx("main.out[0]")]; 87 | yout = w[circuitMAdd.getSignalIdx("main.out[1]")]; 88 | 89 | mg3 = [xout, yout]; 90 | 91 | w = circuitM2E.calculateWitness({ in: mg3}); 92 | 93 | xout = w[circuitM2E.getSignalIdx("main.out[0]")]; 94 | yout = w[circuitM2E.getSignalIdx("main.out[1]")]; 95 | 96 | assert(xout.equals(g3[0])); 97 | assert(yout.equals(g3[1])); 98 | }); 99 | }); 100 | -------------------------------------------------------------------------------- /circomlib/test/pedersen.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const compiler = require("circom"); 5 | 6 | const assert = chai.assert; 7 | 8 | const bigInt = snarkjs.bigInt; 9 | 10 | const babyJub = require("../src/babyjub.js"); 11 | 12 | const PBASE = 13 | [ 14 | [bigInt("10457101036533406547632367118273992217979173478358440826365724437999023779287"),bigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317")], 15 | [bigInt("2671756056509184035029146175565761955751135805354291559563293617232983272177"),bigInt("2663205510731142763556352975002641716101654201788071096152948830924149045094")], 16 | [bigInt("5802099305472655231388284418920769829666717045250560929368476121199858275951"),bigInt("5980429700218124965372158798884772646841287887664001482443826541541529227896")], 17 | [bigInt("7107336197374528537877327281242680114152313102022415488494307685842428166594"),bigInt("2857869773864086953506483169737724679646433914307247183624878062391496185654")], 18 | [bigInt("20265828622013100949498132415626198973119240347465898028410217039057588424236"),bigInt("1160461593266035632937973507065134938065359936056410650153315956301179689506")] 19 | ]; 20 | 21 | describe("Double Pedersen test", function() { 22 | let circuit; 23 | this.timeout(100000); 24 | before( async() => { 25 | const cirDef = await compiler(path.join(__dirname, "circuits", "pedersen_test.circom")); 26 | 27 | circuit = new snarkjs.Circuit(cirDef); 28 | 29 | console.log("NConstrains: " + circuit.nConstraints); 30 | }); 31 | it("Should pedersen at zero", async () => { 32 | 33 | let w, xout, yout; 34 | 35 | w = circuit.calculateWitness({ in: ["0", "0"]}); 36 | 37 | xout = w[circuit.getSignalIdx("main.out[0]")]; 38 | yout = w[circuit.getSignalIdx("main.out[1]")]; 39 | 40 | assert(xout.equals("0")); 41 | assert(yout.equals("1")); 42 | }); 43 | it("Should pedersen at one first generator", async () => { 44 | let w, xout, yout; 45 | 46 | w = circuit.calculateWitness({ in: ["1", "0"]}); 47 | 48 | xout = bigInt(w[circuit.getSignalIdx("main.out[0]")]); 49 | yout = bigInt(w[circuit.getSignalIdx("main.out[1]")]); 50 | 51 | assert(xout.equals(PBASE[0][0])); 52 | assert(yout.equals(PBASE[0][1])); 53 | }); 54 | it("Should pedersen at one second generator", async () => { 55 | let w, xout, yout; 56 | 57 | w = circuit.calculateWitness({ in: ["0", "1"]}); 58 | 59 | xout = w[circuit.getSignalIdx("main.out[0]")]; 60 | yout = w[circuit.getSignalIdx("main.out[1]")]; 61 | 62 | assert(xout.equals(PBASE[1][0])); 63 | assert(yout.equals(PBASE[1][1])); 64 | 65 | }); 66 | it("Should pedersen at mixed generators", async () => { 67 | let w, xout, yout; 68 | w = circuit.calculateWitness({ in: ["3", "7"]}); 69 | 70 | xout = w[circuit.getSignalIdx("main.out[0]")]; 71 | yout = w[circuit.getSignalIdx("main.out[1]")]; 72 | 73 | 74 | const r = babyJub.addPoint( 75 | babyJub.mulPointEscalar(PBASE[0], 3), 76 | babyJub.mulPointEscalar(PBASE[1], 7) 77 | ); 78 | 79 | assert(xout.equals(r[0])); 80 | assert(yout.equals(r[1])); 81 | 82 | }); 83 | it("Should pedersen all ones", async () => { 84 | let w, xout, yout; 85 | 86 | const allOnes = bigInt("1").shl(250).sub(bigInt("1")); 87 | w = circuit.calculateWitness({ in: [allOnes, allOnes]}); 88 | 89 | xout = w[circuit.getSignalIdx("main.out[0]")]; 90 | yout = w[circuit.getSignalIdx("main.out[1]")]; 91 | 92 | const r2 = babyJub.addPoint( 93 | babyJub.mulPointEscalar(PBASE[0], allOnes), 94 | babyJub.mulPointEscalar(PBASE[1], allOnes) 95 | ); 96 | 97 | assert(xout.equals(r2[0])); 98 | assert(yout.equals(r2[1])); 99 | }); 100 | }); 101 | -------------------------------------------------------------------------------- /circomlib/test/pedersen2.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const compiler = require("circom"); 5 | 6 | const assert = chai.assert; 7 | 8 | const bigInt = snarkjs.bigInt; 9 | 10 | const babyJub = require("../src/babyjub.js"); 11 | const pedersen = require("../src/pedersenHash.js"); 12 | 13 | 14 | describe("Pedersen test", function() { 15 | let circuit; 16 | this.timeout(100000); 17 | before( async() => { 18 | const cirDef = await compiler(path.join(__dirname, "circuits", "pedersen2_test.circom")); 19 | 20 | circuit = new snarkjs.Circuit(cirDef); 21 | 22 | console.log("NConstrains Pedersen2: " + circuit.nConstraints); 23 | }); 24 | it("Should pedersen at zero", async () => { 25 | 26 | let w, xout, yout; 27 | 28 | w = circuit.calculateWitness({ in: 0}); 29 | 30 | xout = w[circuit.getSignalIdx("main.out[0]")]; 31 | yout = w[circuit.getSignalIdx("main.out[1]")]; 32 | 33 | const b = Buffer.alloc(32); 34 | 35 | const h = pedersen.hash(b); 36 | const hP = babyJub.unpackPoint(h); 37 | 38 | /* 39 | console.log(`[${xout.toString()}, ${yout.toString()}]`); 40 | console.log(`[${hP[0].toString()}, ${hP[1].toString()}]`); 41 | */ 42 | 43 | assert(xout.equals(hP[0])); 44 | assert(yout.equals(hP[1])); 45 | }); 46 | it("Should pedersen with 253 ones", async () => { 47 | 48 | let w, xout, yout; 49 | 50 | const n = bigInt.one.shl(253).sub(bigInt.one); 51 | console.log(n.toString(16)); 52 | 53 | w = circuit.calculateWitness({ in: n}); 54 | 55 | xout = w[circuit.getSignalIdx("main.out[0]")]; 56 | yout = w[circuit.getSignalIdx("main.out[1]")]; 57 | 58 | const b = Buffer.alloc(32); 59 | for (let i=0; i<31; i++) b[i] = 0xFF; 60 | b[31] = 0x1F; 61 | 62 | 63 | const h = pedersen.hash(b); 64 | const hP = babyJub.unpackPoint(h); 65 | 66 | /* 67 | console.log(`[${xout.toString()}, ${yout.toString()}]`); 68 | console.log(`[${hP[0].toString()}, ${hP[1].toString()}]`); 69 | */ 70 | 71 | assert(xout.equals(hP[0])); 72 | assert(yout.equals(hP[1])); 73 | }); 74 | }); 75 | -------------------------------------------------------------------------------- /circomlib/test/point2bits.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const compiler = require("circom"); 5 | 6 | const assert = chai.assert; 7 | 8 | const bigInt = snarkjs.bigInt; 9 | 10 | const babyJub = require("../src/babyjub.js"); 11 | 12 | 13 | describe("Point 2 bits test", function() { 14 | let circuit; 15 | this.timeout(100000); 16 | before( async() => { 17 | const cirDef = await compiler(path.join(__dirname, "circuits", "pointbits_loopback.circom")); 18 | 19 | circuit = new snarkjs.Circuit(cirDef); 20 | 21 | console.log("NConstrains Point2Bits loopback: " + circuit.nConstraints); 22 | }); 23 | it("Should do the both convertions for 8Base", async () => { 24 | const w = circuit.calculateWitness({ in: babyJub.Base8}); 25 | 26 | assert(circuit.checkWitness(w)); 27 | }); 28 | it("Should do the both convertions for Zero point", async () => { 29 | const w = circuit.calculateWitness({ in: [0, 1]}); 30 | 31 | assert(circuit.checkWitness(w)); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /circomlib/test/poseidoncircuit.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const snarkjs = require("snarkjs"); 4 | const compiler = require("circom"); 5 | var blake2b = require('blake2b'); 6 | 7 | const poseidon = require("../src/poseidon.js"); 8 | 9 | const assert = chai.assert; 10 | 11 | describe("Blake2b version test", function() { 12 | it("Should give the expected output for blake2b version", async () => { 13 | var output = new Uint8Array(32); 14 | var input = Buffer.from('poseidon_constants'); 15 | h = blake2b(output.length).update(input).digest('hex') 16 | assert.equal('e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1', h); 17 | }); 18 | }); 19 | 20 | describe("Poseidon Circuit test", function () { 21 | let circuit; 22 | 23 | this.timeout(100000); 24 | 25 | before( async () => { 26 | const cirDef = await compiler(path.join(__dirname, "circuits", "poseidon_test.circom")); 27 | 28 | circuit = new snarkjs.Circuit(cirDef); 29 | 30 | console.log("Poseidon constraints: " + circuit.nConstraints); 31 | }); 32 | 33 | it("Should check constrain of hash([1, 2])", async () => { 34 | const w = circuit.calculateWitness({inputs: [1, 2]}); 35 | 36 | const res = w[circuit.getSignalIdx("main.out")]; 37 | 38 | const hash = poseidon.createHash(6, 8, 57); 39 | 40 | const res2 = hash([1,2]); 41 | assert.equal('12242166908188651009877250812424843524687801523336557272219921456462821518061', res2.toString()); 42 | assert.equal(res.toString(), res2.toString()); 43 | assert(circuit.checkWitness(w)); 44 | }); 45 | 46 | it("Should check constrain of hash([3, 4])", async () => { 47 | const w = circuit.calculateWitness({inputs: [3, 4]}); 48 | 49 | const res = w[circuit.getSignalIdx("main.out")]; 50 | 51 | const hash = poseidon.createHash(6, 8, 57); 52 | 53 | const res2 = hash([3, 4]); 54 | assert.equal('17185195740979599334254027721507328033796809509313949281114643312710535000993', res2.toString()); 55 | 56 | assert.equal(res.toString(), res2.toString()); 57 | 58 | assert(circuit.checkWitness(w)); 59 | }); 60 | }); 61 | -------------------------------------------------------------------------------- /circomlib/test/poseidoncontract.js: -------------------------------------------------------------------------------- 1 | const ganache = require("ganache-cli"); 2 | const Web3 = require("web3"); 3 | const chai = require("chai"); 4 | const poseidonGenContract = require("../src/poseidon_gencontract.js"); 5 | const Poseidon = require("../src/poseidon.js"); 6 | const bigInt = require("snarkjs").bigInt; 7 | 8 | const assert = chai.assert; 9 | const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); }; 10 | 11 | const SEED = "mimc"; 12 | 13 | describe("Poseidon Smart contract test", () => { 14 | let testrpc; 15 | let web3; 16 | let mimc; 17 | let accounts; 18 | 19 | before(async () => { 20 | web3 = new Web3(ganache.provider(), null, { transactionConfirmationBlocks: 1 }); 21 | accounts = await web3.eth.getAccounts(); 22 | }); 23 | 24 | it("Should deploy the contract", async () => { 25 | const C = new web3.eth.Contract(poseidonGenContract.abi); 26 | 27 | mimc = await C.deploy({ 28 | data: poseidonGenContract.createCode() 29 | }).send({ 30 | gas: 2500000, 31 | from: accounts[0] 32 | }); 33 | }); 34 | 35 | it("Shold calculate the mimic correctly", async () => { 36 | 37 | const res = await mimc.methods.poseidon([1,2]).call(); 38 | 39 | // console.log("Cir: " + bigInt(res.toString(16)).toString(16)); 40 | 41 | const hash = Poseidon.createHash(6, 8, 57); 42 | 43 | const res2 = hash([1,2]); 44 | // console.log("Ref: " + bigInt(res2).toString(16)); 45 | 46 | assert.equal(res.toString(), res2.toString()); 47 | }); 48 | }); 49 | 50 | -------------------------------------------------------------------------------- /circomlib/test/rawsmt3.circom: -------------------------------------------------------------------------------- 1 | 2 | include "../circuits/smt/smtverifier.circom"; 3 | template SMT(nLevels) { 4 | signal input root; 5 | signal input mtp[nLevels]; 6 | signal input hi; 7 | signal input hv; 8 | 9 | component smtClaimExists = SMTVerifier(nLevels); 10 | smtClaimExists.enabled <== 1; 11 | smtClaimExists.fnc <== 0; 12 | smtClaimExists.root <== root; 13 | for (var i=0; i { 29 | let circuit; 30 | before( async() => { 31 | const cirDef = await compiler(path.join(__dirname, "circuits", "sign_test.circom")); 32 | 33 | circuit = new snarkjs.Circuit(cirDef); 34 | 35 | console.log("NConstrains: " + circuit.nConstraints); 36 | }); 37 | 38 | it("Sign of 0", async () => { 39 | const inp = getBits(bigInt.zero, 254); 40 | const w = circuit.calculateWitness({in: inp}); 41 | 42 | assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)) ); 43 | }); 44 | 45 | it("Sign of 3", async () => { 46 | const inp = getBits(bigInt(3), 254); 47 | const w = circuit.calculateWitness({in: inp}); 48 | 49 | assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)) ); 50 | }); 51 | 52 | it("Sign of q/2", async () => { 53 | const inp = getBits(q.shr(bigInt.one), 254); 54 | const w = circuit.calculateWitness({in: inp}); 55 | 56 | assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)) ); 57 | }); 58 | 59 | it("Sign of q/2+1", async () => { 60 | const inp = getBits(q.shr(bigInt.one).add(bigInt.one), 254); 61 | const w = circuit.calculateWitness({in: inp}); 62 | 63 | assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) ); 64 | }); 65 | 66 | it("Sign of q-1", async () => { 67 | const inp = getBits(q.sub(bigInt.one), 254); 68 | const w = circuit.calculateWitness({in: inp}); 69 | 70 | assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) ); 71 | }); 72 | 73 | it("Sign of q", async () => { 74 | const inp = getBits(q, 254); 75 | const w = circuit.calculateWitness({in: inp}); 76 | 77 | assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) ); 78 | }); 79 | 80 | it("Sign of all ones", async () => { 81 | const inp = getBits(bigInt(1).shl(254).sub(bigInt(1)), 254); 82 | const w = circuit.calculateWitness({in: inp}); 83 | 84 | assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) ); 85 | }); 86 | 87 | 88 | }); 89 | -------------------------------------------------------------------------------- /circomlib/test/smtverifier_adria.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const snarkjs = require("snarkjs"); 3 | const compiler = require("circom"); 4 | const fs = require("fs") 5 | 6 | const bigInt = snarkjs.bigInt; 7 | const smt = require("../src/smt.js"); 8 | 9 | const circuitSource = ` 10 | include "../circuits/smt/smtverifier.circom"; 11 | template SMT(nLevels) { 12 | signal input root; 13 | signal input mtp[nLevels]; 14 | signal input hi; 15 | signal input hv; 16 | 17 | component smtClaimExists = SMTVerifier(nLevels); 18 | smtClaimExists.enabled <== 1; 19 | smtClaimExists.fnc <== 0; 20 | smtClaimExists.root <== root; 21 | for (var i=0; i { 40 | circuitFileName = path.join(__dirname, ".", "rawsmt3.circom"); 41 | fs.writeFileSync(circuitFileName,circuitSource); 42 | }); 43 | 44 | const levels = 4; 45 | async function testsmt3(e1, e2) { 46 | let tree = await smt.newMemEmptyTrie(); 47 | 48 | // insert e1, e2 49 | await tree.insert(e1.hi, e1.hv); 50 | await tree.insert(e2.hi, e2.hv); 51 | 52 | // generate proof for e1 53 | const findInfo = await tree.find(e1.hi); 54 | const siblings = findInfo.siblings; 55 | while (siblings.length < levels) siblings.push(bigInt(0)); 56 | 57 | const input = { 58 | root: tree.root, 59 | mtp: siblings, 60 | hi: e1.hi, 61 | hv: e1.hv, 62 | }; 63 | 64 | const compiledCircuit = await compiler( 65 | circuitFileName, 66 | { reduceConstraints: false } 67 | ); 68 | 69 | const circuit = new snarkjs.Circuit(compiledCircuit); 70 | const witness = circuit.calculateWitness(input); 71 | circuit.checkWitness(witness); 72 | } 73 | 74 | it("TestSmts", async () => { 75 | 76 | const e1 = { 77 | hi: bigInt("17124152697573569611556136390143205198134245887034837071647643529178599000839"), 78 | hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"), 79 | }; 80 | 81 | const e2ok = { 82 | hi: bigInt("16498254692537945203721083102154618658340563351558973077349594629411025251262"), 83 | hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"), 84 | }; 85 | 86 | const e2fail = { 87 | hi: bigInt("17195092312975762537892237130737365903429674363577646686847513978084990105579"), 88 | hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"), 89 | }; 90 | 91 | console.log("test e1, e2ok"); 92 | await testsmt3(e1, e2ok); 93 | 94 | console.log("test e1, e2fail"); 95 | await testsmt3(e1, e2fail); 96 | }); 97 | }); 98 | 99 | -------------------------------------------------------------------------------- /circuit/generate_leaf_existence_input.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const mimcjs = require("../circomlib/src/mimc7.js"); 3 | 4 | 5 | const nullifierHash = mimcjs.hash(255,0) 6 | 7 | const root= "21150603275199036235447464146889900632582816435445773009431960038115036290869" 8 | 9 | // console.info(nullifierHash.toString()) 10 | 11 | // 主要是这里 12 | // root,paths2_root,paths2_root_pos 从链上获得 13 | // nullifierHash 链下计算 leaf_index + secret 14 | 15 | const inputs = { 16 | "root":root, 17 | "nullifierHash":nullifierHash.toString(), 18 | 19 | "secret":"0", 20 | "paths2_root":[ 21 | "0", 22 | "11730251359286723731141466095709901450170369094578288842486979042586033922425", 23 | "9246143820134657901174176070515121907817622693387763521229610032056676659170", 24 | "3919701857960328675810908960351443394156342162925591865624975500788003961839", 25 | "11868459870544964516983456008242250460119356993157504951373700810334626455267", 26 | "17452340833314273101389791943519612073692685328163719737408744891984034913325", 27 | "5253775198292439148470029927208469781432760606734473405438165226265735347735", 28 | "9586203148669237657308746417333646936338855598595657703565568663564319347700" 29 | ], 30 | "paths2_root_pos":[ 31 | 1, 32 | 1, 33 | 1, 34 | 1, 35 | 1, 36 | 1, 37 | 1, 38 | 1 39 | ] 40 | } 41 | 42 | console.info(inputs) 43 | 44 | fs.writeFileSync( 45 | "./input.json", 46 | JSON.stringify(inputs), 47 | "utf-8" 48 | ); 49 | 50 | // test 51 | 52 | 53 | // var a = mimcjs.hash("11730251359286723731141466095709901450170369094578288842486979042586033922425","0") 54 | // // 1,0 55 | // console.info(a) 56 | // a =mimcjs.hash(a,"11730251359286723731141466095709901450170369094578288842486979042586033922425") 57 | // // 2,0 58 | // console.info(a) 59 | // a =mimcjs.hash(a,"9246143820134657901174176070515121907817622693387763521229610032056676659170") 60 | // //3,0 61 | // console.info(a) 62 | // a =mimcjs.hash(a,"3919701857960328675810908960351443394156342162925591865624975500788003961839") 63 | // // 4,0 64 | // console.info(a) 65 | // a =mimcjs.hash(a,"11868459870544964516983456008242250460119356993157504951373700810334626455267") 66 | // // 5,0 67 | // console.info(a) 68 | // a =mimcjs.hash(a,"17452340833314273101389791943519612073692685328163719737408744891984034913325") 69 | // // 6,0 70 | // console.info(a) 71 | // a =mimcjs.hash(a,"5253775198292439148470029927208469781432760606734473405438165226265735347735") 72 | // // 7,0 73 | // console.info(a) 74 | 75 | 76 | 77 | // a =mimcjs.hash(a,"9586203148669237657308746417333646936338855598595657703565568663564319347700") 78 | // console.info(a) 79 | 80 | 81 | -------------------------------------------------------------------------------- /circuit/get_merkle_root.circom: -------------------------------------------------------------------------------- 1 | include "../circomlib/circuits/mimc.circom"; 2 | 3 | template GetMerkleRoot(k){ 4 | // k is depth of tree 5 | 6 | signal input leaf; 7 | signal input paths2_root[k]; 8 | signal input paths2_root_pos[k]; 9 | 10 | signal output out; 11 | 12 | // hash of first two entries in tx Merkle proof 13 | component merkle_root[k]; 14 | merkle_root[0] = MiMC7(91); 15 | merkle_root[0].x_in <== paths2_root[0] - paths2_root_pos[0]* (paths2_root[0] - leaf); 16 | merkle_root[0].k <== leaf - paths2_root_pos[0]* (leaf - paths2_root[0]); 17 | 18 | // hash of all other entries in tx Merkle proof 19 | for (var v = 1; v < k; v++){ 20 | merkle_root[v] = MiMC7(91); 21 | merkle_root[v].x_in <== paths2_root[v] - paths2_root_pos[v]* (paths2_root[v] - merkle_root[v-1].out); 22 | merkle_root[v].k<== merkle_root[v-1].out - paths2_root_pos[v]* (merkle_root[v-1].out - paths2_root[v]); 23 | 24 | } 25 | 26 | // output computed Merkle root 27 | out <== merkle_root[k-1].out; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /circuit/input.json: -------------------------------------------------------------------------------- 1 | {"root":"21150603275199036235447464146889900632582816435445773009431960038115036290869","nullifierHash":"8112587267332776847096965636706065951984180935722389598817594570457611916925","secret":"0","paths2_root":["0","11730251359286723731141466095709901450170369094578288842486979042586033922425","9246143820134657901174176070515121907817622693387763521229610032056676659170","3919701857960328675810908960351443394156342162925591865624975500788003961839","11868459870544964516983456008242250460119356993157504951373700810334626455267","17452340833314273101389791943519612073692685328163719737408744891984034913325","5253775198292439148470029927208469781432760606734473405438165226265735347735","9586203148669237657308746417333646936338855598595657703565568663564319347700"],"paths2_root_pos":[1,1,1,1,1,1,1,1]} -------------------------------------------------------------------------------- /circuit/mixer.circom: -------------------------------------------------------------------------------- 1 | include "./get_merkle_root.circom"; 2 | include "../circomlib/circuits/mimc.circom"; 3 | include "../circomlib/circuits/bitify.circom"; 4 | 5 | template Withdraw(k){ 6 | // public input 7 | signal input root; 8 | signal input nullifierHash; 9 | 10 | // private input 11 | signal private input secret; 12 | 13 | signal private input paths2_root[k]; 14 | signal private input paths2_root_pos[k]; 15 | 16 | // root constrain 17 | component leaf = MiMC7(91); 18 | leaf.x_in <== secret; 19 | leaf.k <== 0; 20 | 21 | component computed_root = GetMerkleRoot(k); 22 | computed_root.leaf <== leaf.out; 23 | 24 | for (var w = 0; w < k; w++){ 25 | computed_root.paths2_root[w] <== paths2_root[w]; 26 | computed_root.paths2_root_pos[w] <== paths2_root_pos[w]; 27 | } 28 | root === computed_root.out; 29 | 30 | // nullifier constrain 31 | component cmt_index = Bits2Num(k); 32 | for (var i =0 ;i < k ; i++){ 33 | cmt_index.in[i] <== paths2_root_pos[i]; 34 | } 35 | 36 | component nullifier = MiMC7(91); 37 | nullifier.x_in <== cmt_index.out; 38 | nullifier.k <== secret; 39 | 40 | nullifierHash === nullifier.out; 41 | 42 | } 43 | 44 | component main = Withdraw(8); -------------------------------------------------------------------------------- /circuit/proof.json: -------------------------------------------------------------------------------- 1 | { 2 | "pi_a": [ 3 | "20877288104095751267585610199913279353618758691437619791686977050129664456389", 4 | "15693617302136481278245538940899381250429149098034952706273556391145393859216", 5 | "1" 6 | ], 7 | "pi_b": [ 8 | [ 9 | "2694001530206951096657034260482657927057064642373327899493389597479910026897", 10 | "20887204188560906221573135530366283219823029531923971704367165893924164103484" 11 | ], 12 | [ 13 | "15353042833167809212463935044855676103217333225993824157047325481411635726305", 14 | "14716018085887155702396643019802409120757967641062479521906190963408945263502" 15 | ], 16 | [ 17 | "1", 18 | "0" 19 | ] 20 | ], 21 | "pi_c": [ 22 | "15107887645556753652731657605721504769491467860457729231997289443151827676534", 23 | "9468349751090501851401951902723824224109281338205538127364527531420239388745", 24 | "1" 25 | ], 26 | "protocol": "groth" 27 | } -------------------------------------------------------------------------------- /circuit/public.json: -------------------------------------------------------------------------------- 1 | [ 2 | "21150603275199036235447464146889900632582816435445773009431960038115036290869", 3 | "8112587267332776847096965636706065951984180935722389598817594570457611916925" 4 | ] -------------------------------------------------------------------------------- /circuit/test.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const mimcjs = require("../circomlib/src/mimc7.js"); 3 | const mimcMerkle = require('./MiMCMerkle.js') 4 | const bigInt = require("snarkjs").bigInt; 5 | 6 | 7 | // console.log("IV: "+mimcjs.getIV().toString()); 8 | 9 | // console.log(mimcjs.getConstants("mimc", 91)) 10 | 11 | // 与Solidity中计算方式不一样 12 | // var a=mimcjs.multiHash([1,1]) 13 | // console.info(a.toString()) 14 | 15 | // 使用这种方式 16 | // var b= mimcjs.hash(1,1) 17 | // console.info(b) 18 | 19 | // test 20 | 21 | // 11730251359286723731141466095709901450170369094578288842486979042586033922425, 22 | // 12240136457100152345096610842396488822128317434453048685489891202497829360467, 23 | // 20808841395409656332564552932284796001294721646723037196107424963391316010609, 24 | // 10513607674170245577899825752483841247286555366379776940083295721103562343571 25 | 26 | // var c = mimcjs.hash("11730251359286723731141466095709901450170369094578288842486979042586033922425","12240136457100152345096610842396488822128317434453048685489891202497829360467") 27 | // var d = mimcjs.hash("20808841395409656332564552932284796001294721646723037196107424963391316010609","10513607674170245577899825752483841247286555366379776940083295721103562343571") 28 | 29 | // console.info(c.toString()) 30 | // console.info(d.toString()) 31 | 32 | // test 0,0 33 | 34 | var e = mimcjs.hash(0,0) 35 | console.info(e) -------------------------------------------------------------------------------- /circuit/verification_key.json: -------------------------------------------------------------------------------- 1 | { 2 | "protocol": "groth", 3 | "nPublic": 2, 4 | "IC": [ 5 | [ 6 | "17714964265504774315832855412112687552033627046648161913181104667161667280182", 7 | "10182152238620976280956833855810523713316887883069012843902335985235503411109", 8 | "1" 9 | ], 10 | [ 11 | "21779613478049291778977808975237620919743197773024579138263548067213376719722", 12 | "6220666918709135287714584405317265078793728198639272199322234450647313503622", 13 | "1" 14 | ], 15 | [ 16 | "20963868377572439714719202674516959269493707757570567821888575173256296227816", 17 | "21727187186062644982057584080468197983197235758006260346001003992642835183751", 18 | "1" 19 | ] 20 | ], 21 | "vk_alfa_1": [ 22 | "19954038906694473095795588300455108542302901779323036204740314236031523633986", 23 | "935032493812782466972697089829497539870102130159527313303791013371341319722", 24 | "1" 25 | ], 26 | "vk_beta_2": [ 27 | [ 28 | "20177504484606866664523849261013362602542415901114295190125010325043412273856", 29 | "9206333877302290249047473384360892236718054704057118685563297901946528576007" 30 | ], 31 | [ 32 | "1770561748979299627401206767402639395904103727265361960030143043944529050956", 33 | "6056546184614372494863912837301520114840105537654720841559671105950445470382" 34 | ], 35 | [ 36 | "1", 37 | "0" 38 | ] 39 | ], 40 | "vk_gamma_2": [ 41 | [ 42 | "17099255796052335977202380708816216091445801311224561780592919583964688987290", 43 | "5771605085985765491228691620539567451085848841223499775615601353560639138293" 44 | ], 45 | [ 46 | "5494435350645967832639045879672220429193328881788749992222633576873819471525", 47 | "18086513422602970315174555311558019572210176555976729708135671911737913723742" 48 | ], 49 | [ 50 | "1", 51 | "0" 52 | ] 53 | ], 54 | "vk_delta_2": [ 55 | [ 56 | "10566664133143161639296180259980862182204296501262474527953113104966757252596", 57 | "7388689103475665691529982415825584954704226977431737322609453254159206883717" 58 | ], 59 | [ 60 | "12540800199150452994537681716884967191365951092971669372228513319201938981218", 61 | "20186472435036777416011485941620206764524419120709110805910707224263830194715" 62 | ], 63 | [ 64 | "1", 65 | "0" 66 | ] 67 | ], 68 | "vk_alfabeta_12": [ 69 | [ 70 | [ 71 | "1079832367271228821871071804604258216417038301845617055411292171008379388720", 72 | "20059587143710585482974068409006089636040298167299136819903287862999329771524" 73 | ], 74 | [ 75 | "19212253551470317806185222994660465110275056142469518727709656878401773404768", 76 | "11511040222534402751261948347813036704344997823571891064411833100382257777155" 77 | ], 78 | [ 79 | "8809690865640118640541335010935136260514382544046685126110058738813601570772", 80 | "20983581752170548601121692759647760810610900460032018989391418329893405457830" 81 | ] 82 | ], 83 | [ 84 | [ 85 | "8859988900815894800153295566582250749956172807251310079402571201056964704285", 86 | "17049946584302621963143989924424944243745482135266881334580289380621564745024" 87 | ], 88 | [ 89 | "2176621689784058831911839127313794890519875978853840158356746413136658807239", 90 | "17867287951171947240000234756815869646539208677246941851563152671789975859708" 91 | ], 92 | [ 93 | "1268151230108258737980983732509610886062738408702724709374114685174190610407", 94 | "10353889643977727869133809395313173523653295536345137575318986198131467325963" 95 | ] 96 | ] 97 | ] 98 | } -------------------------------------------------------------------------------- /contracts/MerkleTree.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.0; 2 | 3 | contract IMimc { 4 | function MiMCpe7(uint256 in_x,uint256 in_k) public returns(uint256 out_x); 5 | } 6 | 7 | contract MerkelTree { 8 | mapping (uint256 => bool) public serials; 9 | mapping (uint256 => bool) public roots; 10 | uint public tree_depth = 8; 11 | uint public no_leaves = 256; 12 | struct Mtree { 13 | uint256 cur; 14 | uint256[256][9] leaves2; // tree depth + 1 15 | } 16 | 17 | Mtree public MT; 18 | 19 | IMimc mimc; 20 | 21 | event LeafAdded(uint256 index); 22 | 23 | event TestMimc(uint256); 24 | 25 | event MerkleProof(uint256[8] , uint256[8] ); 26 | 27 | constructor(address _mimc) public{ 28 | mimc = IMimc(_mimc); 29 | } 30 | 31 | //Merkletree.append(com) 32 | function insert(uint256 com) public returns (uint256 ) { 33 | require (MT.cur != no_leaves ); 34 | MT.leaves2[0][MT.cur] = com; 35 | updateTree(); 36 | emit LeafAdded(MT.cur); 37 | MT.cur++; 38 | 39 | return MT.cur-1; 40 | } 41 | 42 | 43 | function getMerkelProof(uint256 index) public returns (uint256[8] memory, uint256[8] memory) { 44 | 45 | uint256[8] memory address_bits; 46 | uint256[8] memory merkelProof; 47 | 48 | for (uint256 i=0 ; i < tree_depth; i++) { 49 | // address_bits[i] = index%2; 50 | if (index%2 == 0) { 51 | address_bits[i]=1; 52 | merkelProof[i] = getUniqueLeaf(MT.leaves2[i][index + 1],i); 53 | } 54 | else { 55 | address_bits[i]=0; 56 | merkelProof[i] = getUniqueLeaf(MT.leaves2[i][index - 1],i); 57 | } 58 | index = uint256(index/2); 59 | } 60 | emit MerkleProof(merkelProof, address_bits); 61 | return(merkelProof, address_bits); 62 | } 63 | 64 | function getMimc(uint256 input, uint256 sk) public returns ( uint256) { 65 | emit TestMimc(mimc.MiMCpe7(input , sk)); 66 | return mimc.MiMCpe7(input , sk); 67 | } 68 | 69 | function getUniqueLeaf(uint256 leaf, uint256 depth) public returns (uint256) { 70 | if (leaf == 0) { 71 | for (uint256 i=0;i=0.4.21 <0.6.0; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | constructor() public { 8 | owner = msg.sender; 9 | } 10 | 11 | modifier restricted() { 12 | if (msg.sender == owner) _; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /deploy/call_mimc.js: -------------------------------------------------------------------------------- 1 | var Web3 = require("web3"); 2 | var web3 = new Web3(new Web3.providers.HttpProvider('https://ropsten.infura.io/')); 3 | 4 | 5 | var abi = [ 6 | { 7 | "constant": true, 8 | "inputs": [ 9 | { 10 | "name": "in_x", 11 | "type": "uint256" 12 | }, 13 | { 14 | "name": "in_k", 15 | "type": "uint256" 16 | } 17 | ], 18 | "name": "MiMCpe7", 19 | "outputs": [ 20 | { 21 | "name": "out_x", 22 | "type": "uint256" 23 | } 24 | ], 25 | "payable": false, 26 | "stateMutability": "pure", 27 | "type": "function" 28 | } 29 | ]; 30 | 31 | 32 | var MyContract = new web3.eth.Contract(abi, '0x0958C55DF32886A082A4D8e9c7A1BE8bfB8c33e5'); 33 | MyContract.methods.MiMCpe7(1,1).call() 34 | .then(console.log); 35 | 36 | 37 | -------------------------------------------------------------------------------- /deploy/deploy_mimc.js: -------------------------------------------------------------------------------- 1 | const ganache = require("ganache-cli"); 2 | const Web3 = require("web3"); 3 | const chai = require("chai"); 4 | const mimcGenContract = require("../circomlib/src/mimc_gencontract.js"); 5 | const mimcjs = require("../circomlib/src/mimc7.js"); 6 | 7 | 8 | 9 | const assert = chai.assert; 10 | const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); }; 11 | 12 | const SEED = "mimc"; 13 | 14 | describe("MiMC Smart contract test", function () { 15 | let testrpc; 16 | let web3; 17 | let mimc; 18 | let accounts; 19 | 20 | this.timeout(100000); 21 | 22 | before(async () => { 23 | web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"), null, { transactionConfirmationBlocks: 1 }); 24 | accounts = await web3.eth.getAccounts(); 25 | }); 26 | 27 | it("Should deploy the contract", async () => { 28 | const C = new web3.eth.Contract(mimcGenContract.abi); 29 | 30 | mimc = await C.deploy({ 31 | data: mimcGenContract.createCode(SEED, 91), 32 | arguments: [] 33 | }).send({ 34 | gas: 1500000, 35 | gasPrice: '30000000000000', 36 | from: accounts[0] 37 | }).on("error", (error) => { 38 | console.log("ERROR: "+error); 39 | }); 40 | 41 | console.log(mimc.address) 42 | }); 43 | 44 | it("Shold calculate the mimic correctly", async () => { 45 | const res = await mimc.methods.MiMCpe7(1,1).call(); 46 | const res2 = await mimcjs.hash(1,1,91); 47 | console.info(res.toString()) 48 | 49 | assert.equal(res.toString(), res2.toString()); 50 | }); 51 | }); 52 | 53 | -------------------------------------------------------------------------------- /deploy/gen_contract.js: -------------------------------------------------------------------------------- 1 | 2 | const mimcGenContract = require("../circomlib/src/mimc_gencontract.js"); 3 | 4 | 5 | const SEED = "mimc"; 6 | 7 | 8 | async function gen () { 9 | var data = mimcGenContract.createCode(SEED, 91) 10 | 11 | console.info(data.toString()) 12 | } 13 | 14 | gen() 15 | 16 | 17 | -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | const Migrations = artifacts.require("Migrations"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /migrations/2_deploy_contracts.js: -------------------------------------------------------------------------------- 1 | const Mixer = artifacts.require("Mixer"); 2 | 3 | module.exports = async function(deployer, network, accounts) { 4 | if (network === "development") return; // Don't deploy on tests 5 | 6 | // MiniMeTokenFactory send 7 | let MixerFuture = Mixer.new("0x0958C55DF32886A082A4D8e9c7A1BE8bfB8c33e5"); 8 | 9 | // MiniMeTokenFactory wait 10 | let mixer = await MixerFuture; 11 | console.info("mixer: " + mixer.address); 12 | console.info(); 13 | 14 | 15 | }; 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mixer", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "dependencies": { 12 | "bignumber": "^1.1.0", 13 | "bn.js": "^5.0.0", 14 | "circom": "0.0.28", 15 | "markdown-toc": "^1.2.0", 16 | "snarkjs": "^0.1.13", 17 | "truffle-contract": "^4.0.31", 18 | "truffle-hdwallet-provider": "^1.0.17" 19 | }, 20 | "license": "ISC" 21 | } 22 | -------------------------------------------------------------------------------- /truffle.js: -------------------------------------------------------------------------------- 1 | const HDWalletProvider = require('truffle-hdwallet-provider'); 2 | 3 | const setting=require('./scripts/setting.js'); 4 | const mnemonic = setting.getMnemonic(); 5 | 6 | module.exports = { 7 | networks: { 8 | 9 | ropsten: { 10 | provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/14fc7ba5f9004fcdbccb944b09d829e1`), 11 | network_id: 3, // Ropsten's id 12 | gas: 5500000, // Ropsten has a lower block limit than mainnet 13 | }, 14 | 15 | } 16 | }; 17 | --------------------------------------------------------------------------------