├── .github └── workflows │ └── test.yml ├── .gitignore ├── .vscode └── launch.json ├── LICENSE ├── README.md ├── 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 ├── poseidon_constants.circom ├── poseidon_constants_old.circom ├── poseidon_old.circom ├── sha256 │ ├── ch.circom │ ├── constants.circom │ ├── main.circom │ ├── maj.circom │ ├── rotate.circom │ ├── sha256.circom │ ├── sha256_2.circom │ ├── sha256compression.circom │ ├── sha256compression_function.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 └── test ├── aliascheck.js ├── babyjub.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 ├── poseidon3_test.circom ├── poseidon6_test.circom ├── poseidonex_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 ├── eddsamimc.js ├── eddsaposeidon.js ├── escalarmul.js ├── escalarmulany.js ├── escalarmulfix.js ├── helpers ├── printsignal.js └── sha256.js ├── mimccircuit.js ├── mimcspongecircuit.js ├── montgomery.js ├── multiplexer.js ├── pedersen.js ├── pedersen2.js ├── point2bits.js ├── poseidoncircuit.js ├── sha256.js ├── sign.js ├── smtprocessor.js └── smtverifier.js /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | 8 | jobs: 9 | test: 10 | name: Test 11 | runs-on: ${{ matrix.os }} 12 | timeout-minutes: 30 13 | 14 | strategy: 15 | fail-fast: true 16 | matrix: 17 | os: ["ubuntu-latest"] 18 | node-version: ["22"] 19 | 20 | steps: 21 | - name: Checkout project 22 | uses: actions/checkout@v3 23 | 24 | - name: Setup Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v3 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | check-latest: true 29 | cache: "npm" 30 | 31 | - name: Setup Circom 32 | run: wget https://github.com/iden3/circom/releases/latest/download/circom-linux-amd64 && sudo mv ./circom-linux-amd64 /usr/bin/circom && sudo chmod +x /usr/bin/circom 33 | 34 | - name: Install dependencies 35 | run: npm ci 36 | 37 | - name: Run tests 38 | run: npm test 39 | -------------------------------------------------------------------------------- /.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 -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "pwa-node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "skipFiles": [ 12 | "/**" 13 | ], 14 | "program": "${workspaceFolder}/calcoptimizedposeidonconsts/test_poseidon.js", 15 | "cwd": "${workspaceFolder}/calcoptimizedposeidonconsts" 16 | }, 17 | { 18 | "type": "pwa-node", 19 | "request": "launch", 20 | "name": "Tests", 21 | "skipFiles": [ 22 | "/**" 23 | ], 24 | "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", 25 | "cwd": "${workspaceFolder}", 26 | "args": ["test/smtverifier.js"] 27 | }, 28 | { 29 | "type": "pwa-node", 30 | "request": "launch", 31 | "name": "Test Poseidon", 32 | "skipFiles": [ 33 | "/**" 34 | ], 35 | "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", 36 | "cwd": "${workspaceFolder}", 37 | "args": ["test/poseidoncircuit.js"] 38 | }, 39 | { 40 | "type": "pwa-node", 41 | "request": "launch", 42 | "name": "Test binsum", 43 | "skipFiles": [ 44 | "/**" 45 | ], 46 | "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", 47 | "cwd": "${workspaceFolder}", 48 | "args": ["test/binsum.js"] 49 | }, 50 | { 51 | "type": "pwa-node", 52 | "request": "launch", 53 | "name": "Test babyjub", 54 | "skipFiles": [ 55 | "/**" 56 | ], 57 | "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", 58 | "cwd": "${workspaceFolder}", 59 | "args": ["test/babyjub.js"] 60 | } 61 | 62 | ] 63 | } -------------------------------------------------------------------------------- /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 | - You can read more about the circom language in [the circom documentation webpage](https://docs.circom.io/). 8 | 9 | ## Organisation 10 | 11 | This respository contains 3 folders: 12 | - `circuits`: it contains the implementation of different cryptographic primitives in circom language. 13 | - `doc`: it contains some circuit schemes in ASCII (must be opened with Monodraw, an ASCII art editor for Mac). 14 | - `test`: tests. 15 | 16 | A description of the specific circuit templates for the `circuit` folder will be soon updated. 17 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "compconstant.circom"; 22 | 23 | 24 | template AliasCheck() { 25 | 26 | signal input in[254]; 27 | 28 | component compConstant = CompConstant(-1); 29 | 30 | for (var i=0; i<254; i++) in[i] ==> compConstant.in[i]; 31 | 32 | compConstant.out === 0; 33 | } 34 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "bitify.circom"; 22 | include "escalarmulfix.circom"; 23 | 24 | template BabyAdd() { 25 | signal input x1; 26 | signal input y1; 27 | signal input x2; 28 | signal input y2; 29 | signal output xout; 30 | signal output yout; 31 | 32 | signal beta; 33 | signal gamma; 34 | signal delta; 35 | signal tau; 36 | 37 | var a = 168700; 38 | var d = 168696; 39 | 40 | beta <== x1*y2; 41 | gamma <== y1*x2; 42 | delta <== (-a*x1+y1)*(x2 + y2); 43 | tau <== beta * gamma; 44 | 45 | xout <-- (beta + gamma) / (1+ d*tau); 46 | (1+ d*tau) * xout === (beta + gamma); 47 | 48 | yout <-- (delta + a*beta - gamma) / (1-d*tau); 49 | (1-d*tau)*yout === (delta + a*beta - gamma); 50 | } 51 | 52 | template BabyDbl() { 53 | signal input x; 54 | signal input y; 55 | signal output xout; 56 | signal output yout; 57 | 58 | component adder = BabyAdd(); 59 | adder.x1 <== x; 60 | adder.y1 <== y; 61 | adder.x2 <== x; 62 | adder.y2 <== y; 63 | 64 | adder.xout ==> xout; 65 | adder.yout ==> yout; 66 | } 67 | 68 | 69 | template BabyCheck() { 70 | signal input x; 71 | signal input y; 72 | 73 | signal x2; 74 | signal y2; 75 | 76 | var a = 168700; 77 | var d = 168696; 78 | 79 | x2 <== x*x; 80 | y2 <== y*y; 81 | 82 | a*x2 + y2 === 1 + d*x2*y2; 83 | } 84 | 85 | // Extracts the public key from private key 86 | template BabyPbk() { 87 | signal input in; 88 | signal output Ax; 89 | signal output Ay; 90 | 91 | var BASE8[2] = [ 92 | 5299619240641551281634865583518297030282874472190772894086521144482721001553, 93 | 16950150798460657717958625567821834550301663161624707787222815936182638968203 94 | ]; 95 | 96 | component pvkBits = Num2Bits(253); 97 | pvkBits.in <== in; 98 | 99 | component mulFix = EscalarMulFix(253, BASE8); 100 | 101 | var i; 102 | for (i=0; i<253; i++) { 103 | mulFix.e[i] <== pvkBits.out[i]; 104 | } 105 | Ax <== mulFix.out[0]; 106 | Ay <== mulFix.out[1]; 107 | } 108 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 42 | 43 | template BinSub(n) { 44 | signal input in[2][n]; 45 | signal output out[n]; 46 | 47 | signal aux; 48 | 49 | var lin = 2**n; 50 | var lout = 0; 51 | 52 | var i; 53 | 54 | for (i=0; i> i) & 1; 61 | 62 | // Ensure out is binary 63 | out[i] * (out[i] - 1) === 0; 64 | 65 | lout = lout + out[i]*(2**i); 66 | } 67 | 68 | aux <-- (lin >> n) & 1; 69 | aux*(aux-1) === 0; 70 | lout = lout + aux*(2**n); 71 | 72 | // Ensure the sum; 73 | lin === lout; 74 | } 75 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 53 | 54 | function nbits(a) { 55 | var n = 1; 56 | var r = 0; 57 | while (n-1> k) & 1; 89 | 90 | // Ensure out is binary 91 | out[k] * (out[k] - 1) === 0; 92 | 93 | lout += out[k] * e2; 94 | 95 | e2 = e2+e2; 96 | } 97 | 98 | // Ensure the sum; 99 | 100 | lin === lout; 101 | } 102 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "comparators.circom"; 22 | include "aliascheck.circom"; 23 | 24 | 25 | template Num2Bits(n) { 26 | signal input in; 27 | signal output out[n]; 28 | var lc1=0; 29 | 30 | var e2=1; 31 | for (var i = 0; i> i) & 1; 33 | out[i] * (out[i] -1 ) === 0; 34 | lc1 += out[i] * e2; 35 | e2 = e2+e2; 36 | } 37 | 38 | lc1 === in; 39 | } 40 | 41 | template Num2Bits_strict() { 42 | signal input in; 43 | signal output out[254]; 44 | 45 | component aliasCheck = AliasCheck(); 46 | component n2b = Num2Bits(254); 47 | in ==> n2b.in; 48 | 49 | for (var i=0; i<254; i++) { 50 | n2b.out[i] ==> out[i]; 51 | n2b.out[i] ==> aliasCheck.in[i]; 52 | } 53 | } 54 | 55 | template Bits2Num(n) { 56 | signal input in[n]; 57 | signal output out; 58 | var lc1=0; 59 | 60 | var e2 = 1; 61 | for (var i = 0; i out; 67 | } 68 | 69 | template Bits2Num_strict() { 70 | signal input in[254]; 71 | signal output out; 72 | 73 | component aliasCheck = AliasCheck(); 74 | component b2n = Bits2Num(254); 75 | 76 | for (var i=0; i<254; i++) { 77 | in[i] ==> b2n.in[i]; 78 | in[i] ==> aliasCheck.in[i]; 79 | } 80 | 81 | b2n.out ==> out; 82 | } 83 | 84 | template Num2BitsNeg(n) { 85 | signal input in; 86 | signal output out[n]; 87 | var lc1=0; 88 | 89 | component isZero; 90 | 91 | isZero = IsZero(); 92 | 93 | var neg = n == 0 ? 0 : 2**n - in; 94 | 95 | for (var i = 0; i> i) & 1; 97 | out[i] * (out[i] -1 ) === 0; 98 | lc1 += out[i] * 2**i; 99 | } 100 | 101 | in ==> isZero.in; 102 | 103 | 104 | 105 | lc1 + isZero.out * 2**n === 2**n - in; 106 | } 107 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "bitify.circom"; 22 | include "binsum.circom"; 23 | 24 | template IsZero() { 25 | signal input in; 26 | signal output out; 27 | 28 | signal inv; 29 | 30 | inv <-- in!=0 ? 1/in : 0; 31 | 32 | out <== -in*inv +1; 33 | in*out === 0; 34 | } 35 | 36 | 37 | template IsEqual() { 38 | signal input in[2]; 39 | signal output out; 40 | 41 | component isz = IsZero(); 42 | 43 | in[1] - in[0] ==> isz.in; 44 | 45 | isz.out ==> out; 46 | } 47 | 48 | template ForceEqualIfEnabled() { 49 | signal input enabled; 50 | signal input in[2]; 51 | 52 | component isz = IsZero(); 53 | 54 | in[1] - in[0] ==> isz.in; 55 | 56 | (1 - isz.out)*enabled === 0; 57 | } 58 | 59 | /* 60 | // N is the number of bits the input have. 61 | // The MSF is the sign bit. 62 | template LessThan(n) { 63 | signal input in[2]; 64 | signal output out; 65 | 66 | component num2Bits0; 67 | component num2Bits1; 68 | 69 | component adder; 70 | 71 | adder = BinSum(n, 2); 72 | 73 | num2Bits0 = Num2Bits(n); 74 | num2Bits1 = Num2BitsNeg(n); 75 | 76 | in[0] ==> num2Bits0.in; 77 | in[1] ==> num2Bits1.in; 78 | 79 | var i; 80 | for (i=0;i adder.in[0][i]; 82 | num2Bits1.out[i] ==> adder.in[1][i]; 83 | } 84 | 85 | adder.out[n-1] ==> out; 86 | } 87 | */ 88 | 89 | template LessThan(n) { 90 | assert(n <= 252); 91 | signal input in[2]; 92 | signal output out; 93 | 94 | component n2b = Num2Bits(n+1); 95 | 96 | n2b.in <== in[0]+ (1< out; 114 | } 115 | 116 | // N is the number of bits the input have. 117 | // The MSF is the sign bit. 118 | template GreaterThan(n) { 119 | signal input in[2]; 120 | signal output out; 121 | 122 | component lt = LessThan(n); 123 | 124 | lt.in[0] <== in[1]; 125 | lt.in[1] <== in[0]; 126 | lt.out ==> out; 127 | } 128 | 129 | // N is the number of bits the input have. 130 | // The MSF is the sign bit. 131 | template GreaterEqThan(n) { 132 | signal input in[2]; 133 | signal output out; 134 | 135 | component lt = LessThan(n); 136 | 137 | lt.in[0] <== in[1]; 138 | lt.in[1] <== in[0]+1; 139 | lt.out ==> out; 140 | } 141 | 142 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "bitify.circom"; 22 | 23 | // Returns 1 if in (in binary) > ct 24 | 25 | template CompConstant(ct) { 26 | signal input in[254]; 27 | signal output out; 28 | 29 | signal parts[127]; 30 | signal sout; 31 | 32 | var clsb; 33 | var cmsb; 34 | var slsb; 35 | var smsb; 36 | 37 | var sum=0; 38 | 39 | var b = (1 << 128) -1; 40 | var a = 1; 41 | var e = 1; 42 | var i; 43 | 44 | for (i=0;i<127; i++) { 45 | clsb = (ct >> (i*2)) & 1; 46 | cmsb = (ct >> (i*2+1)) & 1; 47 | slsb = in[i*2]; 48 | smsb = in[i*2+1]; 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 | -------------------------------------------------------------------------------- /circuits/eddsa.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 | pragma circom 2.0.0; 20 | 21 | include "compconstant.circom"; 22 | include "pointbits.circom"; 23 | include "pedersen.circom"; 24 | include "escalarmulany.circom"; 25 | include "escalarmulfix.circom"; 26 | 27 | template EdDSAVerifier(n) { 28 | signal input msg[n]; 29 | 30 | signal input A[256]; 31 | signal input R8[256]; 32 | signal input S[256]; 33 | 34 | signal Ax; 35 | signal Ay; 36 | 37 | signal R8x; 38 | signal R8y; 39 | 40 | var i; 41 | 42 | // Ensure S compConstant.in[i]; 48 | } 49 | compConstant.out === 0; 50 | S[254] === 0; 51 | S[255] === 0; 52 | 53 | // Convert A to Field elements (And verify A) 54 | 55 | component bits2pointA = Bits2Point_Strict(); 56 | 57 | for (i=0; i<256; i++) { 58 | bits2pointA.in[i] <== A[i]; 59 | } 60 | Ax <== bits2pointA.out[0]; 61 | Ay <== bits2pointA.out[1]; 62 | 63 | // Convert R8 to Field elements (And verify R8) 64 | 65 | component bits2pointR8 = Bits2Point_Strict(); 66 | 67 | for (i=0; i<256; i++) { 68 | bits2pointR8.in[i] <== R8[i]; 69 | } 70 | R8x <== bits2pointR8.out[0]; 71 | R8y <== bits2pointR8.out[1]; 72 | 73 | // Calculate the h = H(R,A, msg) 74 | 75 | component hash = Pedersen(512+n); 76 | 77 | for (i=0; i<256; i++) { 78 | hash.in[i] <== R8[i]; 79 | hash.in[256+i] <== A[i]; 80 | } 81 | for (i=0; i. 18 | */ 19 | pragma circom 2.0.0; 20 | 21 | include "compconstant.circom"; 22 | include "pointbits.circom"; 23 | include "mimc.circom"; 24 | include "bitify.circom"; 25 | include "escalarmulany.circom"; 26 | include "escalarmulfix.circom"; 27 | 28 | template EdDSAMiMCVerifier() { 29 | signal input enabled; 30 | signal input Ax; 31 | signal input Ay; 32 | 33 | signal input S; 34 | signal input R8x; 35 | signal input R8y; 36 | 37 | signal input M; 38 | 39 | var i; 40 | 41 | // Ensure S compConstant.in[i]; 50 | } 51 | compConstant.in[253] <== 0; 52 | compConstant.out === 0; 53 | 54 | // Calculate the h = H(R,A, msg) 55 | 56 | component hash = MultiMiMC7(5, 91); 57 | hash.in[0] <== R8x; 58 | hash.in[1] <== R8y; 59 | hash.in[2] <== Ax; 60 | hash.in[3] <== Ay; 61 | hash.in[4] <== M; 62 | hash.k <== 0; 63 | 64 | component h2bits = Num2Bits_strict(); 65 | h2bits.in <== hash.out; 66 | 67 | // Calculate second part of the right side: right2 = h*8*A 68 | 69 | // Multiply by 8 by adding it 3 times. This also ensure that the result is in 70 | // the subgroup. 71 | component dbl1 = BabyDbl(); 72 | dbl1.x <== Ax; 73 | dbl1.y <== Ay; 74 | component dbl2 = BabyDbl(); 75 | dbl2.x <== dbl1.xout; 76 | dbl2.y <== dbl1.yout; 77 | component dbl3 = BabyDbl(); 78 | dbl3.x <== dbl2.xout; 79 | dbl3.y <== dbl2.yout; 80 | 81 | // We check that A is not zero. 82 | component isZero = IsZero(); 83 | isZero.in <== dbl3.x; 84 | isZero.out === 0; 85 | 86 | component mulAny = EscalarMulAny(254); 87 | for (i=0; i<254; i++) { 88 | mulAny.e[i] <== h2bits.out[i]; 89 | } 90 | mulAny.p[0] <== dbl3.xout; 91 | mulAny.p[1] <== dbl3.yout; 92 | 93 | 94 | // Compute the right side: right = R8 + right2 95 | 96 | component addRight = BabyAdd(); 97 | addRight.x1 <== R8x; 98 | addRight.y1 <== R8y; 99 | addRight.x2 <== mulAny.out[0]; 100 | addRight.y2 <== mulAny.out[1]; 101 | 102 | // Calculate left side of equation left = S*B8 103 | 104 | var BASE8[2] = [ 105 | 5299619240641551281634865583518297030282874472190772894086521144482721001553, 106 | 16950150798460657717958625567821834550301663161624707787222815936182638968203 107 | ]; 108 | component mulFix = EscalarMulFix(253, BASE8); 109 | for (i=0; i<253; i++) { 110 | mulFix.e[i] <== snum2bits.out[i]; 111 | } 112 | 113 | // Do the comparation left == right if enabled; 114 | 115 | component eqCheckX = ForceEqualIfEnabled(); 116 | eqCheckX.enabled <== enabled; 117 | eqCheckX.in[0] <== mulFix.out[0]; 118 | eqCheckX.in[1] <== addRight.xout; 119 | 120 | component eqCheckY = ForceEqualIfEnabled(); 121 | eqCheckY.enabled <== enabled; 122 | eqCheckY.in[0] <== mulFix.out[1]; 123 | eqCheckY.in[1] <== addRight.yout; 124 | } 125 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "compconstant.circom"; 22 | include "pointbits.circom"; 23 | include "mimcsponge.circom"; 24 | include "bitify.circom"; 25 | include "escalarmulany.circom"; 26 | include "escalarmulfix.circom"; 27 | 28 | template EdDSAMiMCSpongeVerifier() { 29 | signal input enabled; 30 | signal input Ax; 31 | signal input Ay; 32 | 33 | signal input S; 34 | signal input R8x; 35 | signal input R8y; 36 | 37 | signal input M; 38 | 39 | var i; 40 | 41 | // Ensure S compConstant.in[i]; 50 | } 51 | compConstant.in[253] <== 0; 52 | compConstant.out === 0; 53 | 54 | // Calculate the h = H(R,A, msg) 55 | 56 | component hash = MiMCSponge(5, 220, 1); 57 | hash.ins[0] <== R8x; 58 | hash.ins[1] <== R8y; 59 | hash.ins[2] <== Ax; 60 | hash.ins[3] <== Ay; 61 | hash.ins[4] <== M; 62 | hash.k <== 0; 63 | 64 | component h2bits = Num2Bits_strict(); 65 | h2bits.in <== hash.outs[0]; 66 | 67 | // Calculate second part of the right side: right2 = h*8*A 68 | 69 | // Multiply by 8 by adding it 3 times. This also ensure that the result is in 70 | // the subgroup. 71 | component dbl1 = BabyDbl(); 72 | dbl1.x <== Ax; 73 | dbl1.y <== Ay; 74 | component dbl2 = BabyDbl(); 75 | dbl2.x <== dbl1.xout; 76 | dbl2.y <== dbl1.yout; 77 | component dbl3 = BabyDbl(); 78 | dbl3.x <== dbl2.xout; 79 | dbl3.y <== dbl2.yout; 80 | 81 | // We check that A is not zero. 82 | component isZero = IsZero(); 83 | isZero.in <== dbl3.x; 84 | isZero.out === 0; 85 | 86 | component mulAny = EscalarMulAny(254); 87 | for (i=0; i<254; i++) { 88 | mulAny.e[i] <== h2bits.out[i]; 89 | } 90 | mulAny.p[0] <== dbl3.xout; 91 | mulAny.p[1] <== dbl3.yout; 92 | 93 | 94 | // Compute the right side: right = R8 + right2 95 | 96 | component addRight = BabyAdd(); 97 | addRight.x1 <== R8x; 98 | addRight.y1 <== R8y; 99 | addRight.x2 <== mulAny.out[0]; 100 | addRight.y2 <== mulAny.out[1]; 101 | 102 | // Calculate left side of equation left = S*B8 103 | 104 | var BASE8[2] = [ 105 | 5299619240641551281634865583518297030282874472190772894086521144482721001553, 106 | 16950150798460657717958625567821834550301663161624707787222815936182638968203 107 | ]; 108 | component mulFix = EscalarMulFix(253, BASE8); 109 | for (i=0; i<253; i++) { 110 | mulFix.e[i] <== snum2bits.out[i]; 111 | } 112 | 113 | // Do the comparation left == right if enabled; 114 | 115 | component eqCheckX = ForceEqualIfEnabled(); 116 | eqCheckX.enabled <== enabled; 117 | eqCheckX.in[0] <== mulFix.out[0]; 118 | eqCheckX.in[1] <== addRight.xout; 119 | 120 | component eqCheckY = ForceEqualIfEnabled(); 121 | eqCheckY.enabled <== enabled; 122 | eqCheckY.in[0] <== mulFix.out[1]; 123 | eqCheckY.in[1] <== addRight.yout; 124 | } 125 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "compconstant.circom"; 22 | include "poseidon.circom"; 23 | include "bitify.circom"; 24 | include "escalarmulany.circom"; 25 | include "escalarmulfix.circom"; 26 | 27 | template EdDSAPoseidonVerifier() { 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*enabled === 0; 52 | 53 | // Calculate the h = H(R,A, msg) 54 | 55 | component hash = Poseidon(5); 56 | 57 | hash.inputs[0] <== R8x; 58 | hash.inputs[1] <== R8y; 59 | hash.inputs[2] <== Ax; 60 | hash.inputs[3] <== Ay; 61 | hash.inputs[4] <== M; 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*enabled === 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[2] = [ 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 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | function pointAdd(x1,y1,x2,y2) { 22 | var a = 168700; 23 | var d = 168696; 24 | 25 | var res[2]; 26 | res[0] = (x1*y2 + y1*x2) / (1 + d*x1*x2*y1*y2); 27 | res[1] = (y1*y2 - a*x1*x2) / (1 - d*x1*x2*y1*y2); 28 | return res; 29 | } 30 | 31 | function EscalarMulW4Table(base, k) { 32 | var out[16][2]; 33 | 34 | var i; 35 | var p[2]; 36 | 37 | var dbl[2] = base; 38 | 39 | for (i=0; i. 18 | */ 19 | pragma circom 2.0.0; 20 | 21 | template XOR() { 22 | signal input a; 23 | signal input b; 24 | signal output out; 25 | 26 | out <== a + b - 2*a*b; 27 | } 28 | 29 | template AND() { 30 | signal input a; 31 | signal input b; 32 | signal output out; 33 | 34 | out <== a*b; 35 | } 36 | 37 | template OR() { 38 | signal input a; 39 | signal input b; 40 | signal output out; 41 | 42 | out <== a + b - a*b; 43 | } 44 | 45 | template NOT() { 46 | signal input in; 47 | signal output out; 48 | 49 | out <== 1 + in - 2*in; 50 | } 51 | 52 | template NAND() { 53 | signal input a; 54 | signal input b; 55 | signal output out; 56 | 57 | out <== 1 - a*b; 58 | } 59 | 60 | template NOR() { 61 | signal input a; 62 | signal input b; 63 | signal output out; 64 | 65 | out <== a*b + 1 - a - b; 66 | } 67 | 68 | template MultiAND(n) { 69 | signal input in[n]; 70 | signal output out; 71 | component and1; 72 | component and2; 73 | component ands[2]; 74 | if (n==1) { 75 | out <== in[0]; 76 | } else if (n==2) { 77 | and1 = AND(); 78 | and1.a <== in[0]; 79 | and1.b <== in[1]; 80 | out <== and1.out; 81 | } else { 82 | and2 = AND(); 83 | var n1 = n\2; 84 | var n2 = n-n\2; 85 | ands[0] = MultiAND(n1); 86 | ands[1] = MultiAND(n2); 87 | var i; 88 | for (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 | pragma circom 2.0.0; 29 | 30 | template Edwards2Montgomery() { 31 | signal input in[2]; 32 | signal output out[2]; 33 | 34 | out[0] <-- (1 + in[1]) / (1 - in[1]); 35 | out[1] <-- out[0] / in[0]; 36 | 37 | 38 | out[0] * (1-in[1]) === (1 + in[1]); 39 | out[1] * in[0] === out[0]; 40 | } 41 | 42 | /* 43 | 44 | u u - 1 45 | [x, y] = [ ---, ------- ] 46 | v u + 1 47 | 48 | */ 49 | template Montgomery2Edwards() { 50 | signal input in[2]; 51 | signal output out[2]; 52 | 53 | out[0] <-- in[0] / in[1]; 54 | out[1] <-- (in[0] - 1) / (in[0] + 1); 55 | 56 | out[0] * in[1] === in[0]; 57 | out[1] * (in[0] + 1) === in[0] - 1; 58 | } 59 | 60 | 61 | /* 62 | x2 - x1 63 | lamda = --------- 64 | y2 - y1 65 | 66 | x3 + A + x1 + x2 67 | x3 = B * lamda^2 - A - x1 -x2 => lamda^2 = ------------------ 68 | B 69 | 70 | y3 = (2*x1 + x2 + A)*lamda - B*lamda^3 - y1 => 71 | 72 | 73 | => y3 = lamda * ( 2*x1 + x2 + A - x3 - A - x1 - x2) - y1 => 74 | 75 | => y3 = lamda * ( x1 - x3 ) - y1 76 | 77 | ---------- 78 | 79 | y2 - y1 80 | lamda = --------- 81 | x2 - x1 82 | 83 | x3 = B * lamda^2 - A - x1 -x2 84 | 85 | y3 = lamda * ( x1 - x3 ) - y1 86 | 87 | */ 88 | 89 | template MontgomeryAdd() { 90 | signal input in1[2]; 91 | signal input in2[2]; 92 | signal output out[2]; 93 | 94 | var a = 168700; 95 | var d = 168696; 96 | 97 | var A = (2 * (a + d)) / (a - d); 98 | var B = 4 / (a - d); 99 | 100 | signal lamda; 101 | 102 | lamda <-- (in2[1] - in1[1]) / (in2[0] - in1[0]); 103 | lamda * (in2[0] - in1[0]) === (in2[1] - in1[1]); 104 | 105 | out[0] <== B*lamda*lamda - A - in1[0] -in2[0]; 106 | out[1] <== lamda * (in1[0] - out[0]) - in1[1]; 107 | } 108 | 109 | /* 110 | 111 | x1_2 = x1*x1 112 | 113 | 3*x1_2 + 2*A*x1 + 1 114 | lamda = --------------------- 115 | 2*B*y1 116 | 117 | x3 = B * lamda^2 - A - x1 -x1 118 | 119 | y3 = lamda * ( x1 - x3 ) - y1 120 | 121 | */ 122 | template MontgomeryDouble() { 123 | signal input in[2]; 124 | signal output out[2]; 125 | 126 | var a = 168700; 127 | var d = 168696; 128 | 129 | var A = (2 * (a + d)) / (a - d); 130 | var B = 4 / (a - d); 131 | 132 | signal lamda; 133 | signal x1_2; 134 | 135 | x1_2 <== in[0] * in[0]; 136 | 137 | lamda <-- (3*x1_2 + 2*A*in[0] + 1 ) / (2*B*in[1]); 138 | lamda * (2*B*in[1]) === (3*x1_2 + 2*A*in[0] + 1 ); 139 | 140 | out[0] <== B*lamda*lamda - A - 2*in[0]; 141 | out[1] <== lamda * (in[0] - out[0]) - in[1]; 142 | } 143 | -------------------------------------------------------------------------------- /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; 91 | success * (success -1) === 0; 92 | } 93 | 94 | 95 | template Multiplexer(wIn, nIn) { 96 | signal input inp[nIn][wIn]; 97 | signal input sel; 98 | signal output out[wIn]; 99 | component dec = Decoder(nIn); 100 | component ep[wIn]; 101 | 102 | for (var k=0; k dec.inp; 107 | for (var j=0; j ep[j].in1[k]; 110 | dec.out[k] ==> ep[j].in2[k]; 111 | } 112 | ep[j].out ==> out[j]; 113 | } 114 | dec.success === 1; 115 | } 116 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | template MultiMux1(n) { 22 | signal input c[n][2]; // Constants 23 | signal input s; // Selector 24 | signal output out[n]; 25 | 26 | for (var i=0; i mux.s; 46 | 47 | mux.out[0] ==> out; 48 | } 49 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | template MultiMux2(n) { 22 | signal input c[n][4]; // Constants 23 | signal input s[2]; // Selector 24 | signal output out[n]; 25 | 26 | signal a10[n]; 27 | signal a1[n]; 28 | signal a0[n]; 29 | signal a[n]; 30 | 31 | signal s10; 32 | s10 <== s[1] * s[0]; 33 | 34 | for (var i=0; i mux.s[i]; 60 | } 61 | 62 | mux.out[0] ==> out; 63 | } 64 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | template MultiMux3(n) { 22 | signal input c[n][8]; // Constants 23 | signal input s[3]; // Selector 24 | signal output out[n]; 25 | 26 | signal a210[n]; 27 | signal a21[n]; 28 | signal a20[n]; 29 | signal a2[n]; 30 | 31 | signal a10[n]; 32 | signal a1[n]; 33 | signal a0[n]; 34 | signal a[n]; 35 | 36 | // 4 constrains for the intermediary variables 37 | signal s10; 38 | s10 <== s[1] * s[0]; 39 | 40 | for (var i=0; i mux.s[i]; 72 | } 73 | 74 | mux.out[0] ==> out; 75 | } 76 | -------------------------------------------------------------------------------- /circuits/mux4.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 | pragma circom 2.0.0; 20 | 21 | template MultiMux4(n) { 22 | signal input c[n][16]; // Constants 23 | signal input s[4]; // Selector 24 | signal output out[n]; 25 | 26 | signal a3210[n]; 27 | signal a321[n]; 28 | signal a320[n]; 29 | signal a310[n]; 30 | signal a32[n]; 31 | signal a31[n]; 32 | signal a30[n]; 33 | signal a3[n]; 34 | 35 | signal a210[n]; 36 | signal a21[n]; 37 | signal a20[n]; 38 | signal a10[n]; 39 | signal a2[n]; 40 | signal a1[n]; 41 | signal a0[n]; 42 | signal a[n]; 43 | 44 | // 4 constrains for the intermediary variables 45 | signal s10; 46 | s10 <== s[1] * s[0]; 47 | signal s20; 48 | s20 <== s[2] * s[0]; 49 | signal s21; 50 | s21 <== s[2] * s[1]; 51 | signal s210; 52 | s210 <== s21 * s[0]; 53 | 54 | 55 | for (var i=0; i mux.s[i]; 116 | } 117 | 118 | mux.out[0] ==> out; 119 | } 120 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "escalarmul.circom"; 22 | 23 | template Pedersen(n) { 24 | signal input in[n]; 25 | signal output out[2]; 26 | 27 | var nexps = ((n-1) \ 250) + 1; 28 | var nlastbits = n - (nexps-1)*250; 29 | 30 | component escalarMuls[nexps]; 31 | 32 | var PBASE[10][2] = [ 33 | [10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317], 34 | [2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094], 35 | [5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896], 36 | [7107336197374528537877327281242680114152313102022415488494307685842428166594,2857869773864086953506483169737724679646433914307247183624878062391496185654], 37 | [20265828622013100949498132415626198973119240347465898028410217039057588424236,1160461593266035632937973507065134938065359936056410650153315956301179689506], 38 | [1487999857809287756929114517587739322941449154962237464737694709326309567994,14017256862867289575056460215526364897734808720610101650676790868051368668003], 39 | [14618644331049802168996997831720384953259095788558646464435263343433563860015,13115243279999696210147231297848654998887864576952244320558158620692603342236], 40 | [6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695], 41 | [3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506], 42 | [18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481] 43 | 44 | ]; 45 | 46 | var i; 47 | var j; 48 | var nexpbits; 49 | for (i=0; i out[0]; 67 | escalarMuls[nexps-1].out[1] ==> out[1]; 68 | } 69 | -------------------------------------------------------------------------------- /circuits/pointbits.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 | pragma circom 2.0.0; 20 | 21 | include "bitify.circom"; 22 | include "aliascheck.circom"; 23 | include "compconstant.circom"; 24 | include "babyjub.circom"; 25 | 26 | 27 | function sqrt(n) { 28 | 29 | if (n == 0) { 30 | return 0; 31 | } 32 | 33 | // Test that have solution 34 | var res = n ** ((-1) >> 1); 35 | // if (res!=1) assert(false, "SQRT does not exists"); 36 | if (res!=1) return 0; 37 | 38 | var m = 28; 39 | var c = 19103219067921713944291392827692070036145651957329286315305642004821462161904; 40 | var t = n ** 81540058820840996586704275553141814055101440848469862132140264610111; 41 | var r = n ** ((81540058820840996586704275553141814055101440848469862132140264610111+1)>>1); 42 | var sq; 43 | var i; 44 | var b; 45 | var j; 46 | 47 | while ((r != 0)&&(t != 1)) { 48 | sq = t*t; 49 | i = 1; 50 | while (sq!=1) { 51 | i++; 52 | sq = sq*sq; 53 | } 54 | 55 | // b = c ^ m-i-1 56 | b = c; 57 | for (j=0; j< m-i-1; j ++) b = b*b; 58 | 59 | m = i; 60 | c = b*b; 61 | t = t*c; 62 | r = r*b; 63 | } 64 | 65 | if (r < 0 ) { 66 | r = -r; 67 | } 68 | 69 | return r; 70 | } 71 | 72 | 73 | template Bits2Point() { 74 | signal input in[256]; 75 | signal output out[2]; 76 | } 77 | 78 | template Bits2Point_Strict() { 79 | signal input in[256]; 80 | signal output out[2]; 81 | 82 | var i; 83 | 84 | // Check aliasing 85 | component aliasCheckY = AliasCheck(); 86 | for (i=0; i<254; i++) { 87 | aliasCheckY.in[i] <== in[i]; 88 | } 89 | in[254] === 0; 90 | 91 | component b2nY = Bits2Num(254); 92 | for (i=0; i<254; i++) { 93 | b2nY.in[i] <== in[i]; 94 | } 95 | 96 | out[1] <== b2nY.out; 97 | 98 | var a = 168700; 99 | var d = 168696; 100 | 101 | var y2 = out[1] * out[1]; 102 | 103 | var x = sqrt( (1-y2)/(a - d*y2) ); 104 | 105 | if (in[255] == 1) x = -x; 106 | 107 | out[0] <-- x; 108 | 109 | component babyCheck = BabyCheck(); 110 | babyCheck.x <== out[0]; 111 | babyCheck.y <== out[1]; 112 | 113 | component n2bX = Num2Bits(254); 114 | n2bX.in <== out[0]; 115 | component aliasCheckX = AliasCheck(); 116 | for (i=0; i<254; i++) { 117 | aliasCheckX.in[i] <== n2bX.out[i]; 118 | } 119 | 120 | component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808); 121 | for (i=0; i<254; i++) { 122 | signCalc.in[i] <== n2bX.out[i]; 123 | } 124 | 125 | signCalc.out === in[255]; 126 | } 127 | 128 | 129 | template Point2Bits() { 130 | signal input in[2]; 131 | signal output out[256]; 132 | 133 | 134 | } 135 | 136 | template Point2Bits_Strict() { 137 | signal input in[2]; 138 | signal output out[256]; 139 | 140 | var i; 141 | 142 | component n2bX = Num2Bits(254); 143 | n2bX.in <== in[0]; 144 | component n2bY = Num2Bits(254); 145 | n2bY.in <== in[1]; 146 | 147 | component aliasCheckX = AliasCheck(); 148 | component aliasCheckY = AliasCheck(); 149 | for (i=0; i<254; i++) { 150 | aliasCheckX.in[i] <== n2bX.out[i]; 151 | aliasCheckY.in[i] <== n2bY.out[i]; 152 | } 153 | 154 | component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808); 155 | for (i=0; i<254; i++) { 156 | signCalc.in[i] <== n2bX.out[i]; 157 | } 158 | 159 | for (i=0; i<254; i++) { 160 | out[i] <== n2bY.out[i]; 161 | } 162 | out[254] <== 0; 163 | out[255] <== signCalc.out; 164 | } 165 | -------------------------------------------------------------------------------- /circuits/poseidon.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "./poseidon_constants.circom"; 4 | 5 | template Sigma() { 6 | signal input in; 7 | signal output out; 8 | 9 | signal in2; 10 | signal in4; 11 | 12 | in2 <== in*in; 13 | in4 <== in2*in2; 14 | 15 | out <== in4*in; 16 | } 17 | 18 | template Ark(t, C, r) { 19 | signal input in[t]; 20 | signal output out[t]; 21 | 22 | for (var i=0; i0) { 95 | ark[0].in[j] <== inputs[j-1]; 96 | } else { 97 | ark[0].in[j] <== initialState; 98 | } 99 | } 100 | 101 | for (var r = 0; r < nRoundsF\2-1; r++) { 102 | for (var j=0; j0) { 67 | ark[i].in[j] <== inputs[j-1]; 68 | } else { 69 | ark[i].in[j] <== 0; 70 | } 71 | } else { 72 | ark[i].in[j] <== mix[i-1].out[j]; 73 | } 74 | } 75 | 76 | if (i < nRoundsF/2 || i >= nRoundsP + nRoundsF/2) { 77 | k = i < nRoundsF/2 ? i : i - nRoundsP; 78 | mix[i] = Mix(t, M); 79 | for (var j=0; j. 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 | pragma circom 2.0.0; 37 | 38 | template Ch_t(n) { 39 | signal input a[n]; 40 | signal input b[n]; 41 | signal input c[n]; 42 | signal output out[n]; 43 | 44 | for (var k=0; k. 18 | */ 19 | pragma circom 2.0.0; 20 | 21 | template H(x) { 22 | signal output out[32]; 23 | var c[8] = [0x6a09e667, 24 | 0xbb67ae85, 25 | 0x3c6ef372, 26 | 0xa54ff53a, 27 | 0x510e527f, 28 | 0x9b05688c, 29 | 0x1f83d9ab, 30 | 0x5be0cd19]; 31 | 32 | for (var i=0; i<32; i++) { 33 | out[i] <== (c[x] >> i) & 1; 34 | } 35 | } 36 | 37 | template K(x) { 38 | signal output out[32]; 39 | var c[64] = [ 40 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 41 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 42 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 43 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 44 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 45 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 46 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 47 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 48 | ]; 49 | 50 | for (var i=0; i<32; i++) { 51 | out[i] <== (c[x] >> i) & 1; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "sha256_2.circom"; 22 | 23 | template Main() { 24 | signal input a; 25 | signal input b; 26 | signal output out; 27 | 28 | component sha256_2 = Sha256_2(); 29 | 30 | sha256_2.a <== a; 31 | sha256_2.b <== a; 32 | out <== sha256_2.out; 33 | } 34 | 35 | component main = Main(); 36 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 33 | 34 | template Maj_t(n) { 35 | signal input a[n]; 36 | signal input b[n]; 37 | signal input c[n]; 38 | signal output out[n]; 39 | signal mid[n]; 40 | 41 | for (var k=0; k. 18 | */ 19 | pragma circom 2.0.0; 20 | 21 | template RotR(n, r) { 22 | signal input in[n]; 23 | signal output out[n]; 24 | 25 | 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 | pragma circom 2.0.0; 20 | 21 | include "constants.circom"; 22 | include "sha256compression.circom"; 23 | include "../bitify.circom"; 24 | 25 | template Sha256_2() { 26 | signal input a; 27 | signal input b; 28 | signal output out; 29 | 30 | var i; 31 | var k; 32 | 33 | component bits2num = Bits2Num(216); 34 | component num2bits[2]; 35 | 36 | num2bits[0] = Num2Bits(216); 37 | num2bits[1] = Num2Bits(216); 38 | 39 | num2bits[0].in <== a; 40 | num2bits[1].in <== b; 41 | 42 | 43 | component sha256compression = Sha256compression() ; 44 | 45 | component ha0 = H(0); 46 | component hb0 = H(1); 47 | component hc0 = H(2); 48 | component hd0 = H(3); 49 | component he0 = H(4); 50 | component hf0 = H(5); 51 | component hg0 = H(6); 52 | component hh0 = H(7); 53 | 54 | for (k=0; k<32; k++ ) { 55 | sha256compression.hin[0*32+k] <== ha0.out[k]; 56 | sha256compression.hin[1*32+k] <== hb0.out[k]; 57 | sha256compression.hin[2*32+k] <== hc0.out[k]; 58 | sha256compression.hin[3*32+k] <== hd0.out[k]; 59 | sha256compression.hin[4*32+k] <== he0.out[k]; 60 | sha256compression.hin[5*32+k] <== hf0.out[k]; 61 | sha256compression.hin[6*32+k] <== hg0.out[k]; 62 | sha256compression.hin[7*32+k] <== hh0.out[k]; 63 | } 64 | 65 | for (i=0; i<216; i++) { 66 | sha256compression.inp[i] <== num2bits[0].out[215-i]; 67 | sha256compression.inp[i+216] <== num2bits[1].out[215-i]; 68 | } 69 | 70 | sha256compression.inp[432] <== 1; 71 | 72 | for (i=433; i<503; i++) { 73 | sha256compression.inp[i] <== 0; 74 | } 75 | 76 | sha256compression.inp[503] <== 1; 77 | sha256compression.inp[504] <== 1; 78 | sha256compression.inp[505] <== 0; 79 | sha256compression.inp[506] <== 1; 80 | sha256compression.inp[507] <== 1; 81 | sha256compression.inp[508] <== 0; 82 | sha256compression.inp[509] <== 0; 83 | sha256compression.inp[510] <== 0; 84 | sha256compression.inp[511] <== 0; 85 | 86 | for (i=0; i<216; i++) { 87 | bits2num.in[i] <== sha256compression.out[255-i]; 88 | } 89 | 90 | out <== bits2num.out; 91 | } 92 | -------------------------------------------------------------------------------- /circuits/sha256/sha256compression.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 | pragma circom 2.0.0; 20 | 21 | include "constants.circom"; 22 | include "t1.circom"; 23 | include "t2.circom"; 24 | include "../binsum.circom"; 25 | include "sigmaplus.circom"; 26 | include "sha256compression_function.circom"; 27 | 28 | 29 | template Sha256compression() { 30 | signal input hin[256]; 31 | signal input inp[512]; 32 | signal output out[256]; 33 | signal a[65][32]; 34 | signal b[65][32]; 35 | signal c[65][32]; 36 | signal d[65][32]; 37 | signal e[65][32]; 38 | signal f[65][32]; 39 | signal g[65][32]; 40 | signal h[65][32]; 41 | signal w[64][32]; 42 | 43 | 44 | var outCalc[256] = sha256compression(hin, inp); 45 | 46 | var i; 47 | for (i=0; i<256; i++) out[i] <-- outCalc[i]; 48 | 49 | component sigmaPlus[48]; 50 | for (i=0; i<48; i++) sigmaPlus[i] = SigmaPlus(); 51 | 52 | component ct_k[64]; 53 | for (i=0; i<64; i++) ct_k[i] = K(i); 54 | 55 | component t1[64]; 56 | for (i=0; i<64; i++) t1[i] = T1(); 57 | 58 | component t2[64]; 59 | for (i=0; i<64; i++) t2[i] = T2(); 60 | 61 | component suma[64]; 62 | for (i=0; i<64; i++) suma[i] = BinSum(32, 2); 63 | 64 | component sume[64]; 65 | for (i=0; i<64; i++) sume[i] = BinSum(32, 2); 66 | 67 | component fsum[8]; 68 | for (i=0; i<8; i++) fsum[i] = BinSum(32, 2); 69 | 70 | var k; 71 | var t; 72 | 73 | for (t=0; t<64; t++) { 74 | if (t<16) { 75 | for (k=0; k<32; k++) { 76 | w[t][k] <== inp[t*32+31-k]; 77 | } 78 | } else { 79 | for (k=0; k<32; k++) { 80 | sigmaPlus[t-16].in2[k] <== w[t-2][k]; 81 | sigmaPlus[t-16].in7[k] <== w[t-7][k]; 82 | sigmaPlus[t-16].in15[k] <== w[t-15][k]; 83 | sigmaPlus[t-16].in16[k] <== w[t-16][k]; 84 | } 85 | 86 | for (k=0; k<32; k++) { 87 | w[t][k] <== sigmaPlus[t-16].out[k]; 88 | } 89 | } 90 | } 91 | 92 | for (k=0; k<32; k++ ) { 93 | a[0][k] <== hin[k]; 94 | b[0][k] <== hin[32*1 + k]; 95 | c[0][k] <== hin[32*2 + k]; 96 | d[0][k] <== hin[32*3 + k]; 97 | e[0][k] <== hin[32*4 + k]; 98 | f[0][k] <== hin[32*5 + k]; 99 | g[0][k] <== hin[32*6 + k]; 100 | h[0][k] <== hin[32*7 + k]; 101 | } 102 | 103 | for (t = 0; t<64; t++) { 104 | for (k=0; k<32; k++) { 105 | t1[t].h[k] <== h[t][k]; 106 | t1[t].e[k] <== e[t][k]; 107 | t1[t].f[k] <== f[t][k]; 108 | t1[t].g[k] <== g[t][k]; 109 | t1[t].k[k] <== ct_k[t].out[k]; 110 | t1[t].w[k] <== w[t][k]; 111 | 112 | t2[t].a[k] <== a[t][k]; 113 | t2[t].b[k] <== b[t][k]; 114 | t2[t].c[k] <== c[t][k]; 115 | } 116 | 117 | for (k=0; k<32; k++) { 118 | sume[t].in[0][k] <== d[t][k]; 119 | sume[t].in[1][k] <== t1[t].out[k]; 120 | 121 | suma[t].in[0][k] <== t1[t].out[k]; 122 | suma[t].in[1][k] <== t2[t].out[k]; 123 | } 124 | 125 | for (k=0; k<32; k++) { 126 | h[t+1][k] <== g[t][k]; 127 | g[t+1][k] <== f[t][k]; 128 | f[t+1][k] <== e[t][k]; 129 | e[t+1][k] <== sume[t].out[k]; 130 | d[t+1][k] <== c[t][k]; 131 | c[t+1][k] <== b[t][k]; 132 | b[t+1][k] <== a[t][k]; 133 | a[t+1][k] <== suma[t].out[k]; 134 | } 135 | } 136 | 137 | for (k=0; k<32; k++) { 138 | fsum[0].in[0][k] <== hin[32*0+k]; 139 | fsum[0].in[1][k] <== a[64][k]; 140 | fsum[1].in[0][k] <== hin[32*1+k]; 141 | fsum[1].in[1][k] <== b[64][k]; 142 | fsum[2].in[0][k] <== hin[32*2+k]; 143 | fsum[2].in[1][k] <== c[64][k]; 144 | fsum[3].in[0][k] <== hin[32*3+k]; 145 | fsum[3].in[1][k] <== d[64][k]; 146 | fsum[4].in[0][k] <== hin[32*4+k]; 147 | fsum[4].in[1][k] <== e[64][k]; 148 | fsum[5].in[0][k] <== hin[32*5+k]; 149 | fsum[5].in[1][k] <== f[64][k]; 150 | fsum[6].in[0][k] <== hin[32*6+k]; 151 | fsum[6].in[1][k] <== g[64][k]; 152 | fsum[7].in[0][k] <== hin[32*7+k]; 153 | fsum[7].in[1][k] <== h[64][k]; 154 | } 155 | 156 | for (k=0; k<32; k++) { 157 | out[31-k] === fsum[0].out[k]; 158 | out[32+31-k] === fsum[1].out[k]; 159 | out[64+31-k] === fsum[2].out[k]; 160 | out[96+31-k] === fsum[3].out[k]; 161 | out[128+31-k] === fsum[4].out[k]; 162 | out[160+31-k] === fsum[5].out[k]; 163 | out[192+31-k] === fsum[6].out[k]; 164 | out[224+31-k] === fsum[7].out[k]; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /circuits/sha256/sha256compression_function.circom: -------------------------------------------------------------------------------- 1 | // signal input hin[256]; 2 | // signal input inp[512]; 3 | // signal output out[256]; 4 | pragma circom 2.0.0; 5 | 6 | function rrot(x, n) { 7 | return ((x >> n) | (x << (32-n))) & 0xFFFFFFFF; 8 | } 9 | 10 | function bsigma0(x) { 11 | return rrot(x,2) ^ rrot(x,13) ^ rrot(x,22); 12 | } 13 | 14 | function bsigma1(x) { 15 | return rrot(x,6) ^ rrot(x,11) ^ rrot(x,25); 16 | } 17 | 18 | function ssigma0(x) { 19 | return rrot(x,7) ^ rrot(x,18) ^ (x >> 3); 20 | } 21 | 22 | function ssigma1(x) { 23 | return rrot(x,17) ^ rrot(x,19) ^ (x >> 10); 24 | } 25 | 26 | function Maj(x, y, z) { 27 | return (x&y) ^ (x&z) ^ (y&z); 28 | } 29 | 30 | function Ch(x, y, z) { 31 | return (x & y) ^ ((0xFFFFFFFF ^x) & z); 32 | } 33 | 34 | function sha256K(i) { 35 | var k[64] = [ 36 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 37 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 38 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 39 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 40 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 41 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 42 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 43 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 44 | ]; 45 | return k[i]; 46 | } 47 | 48 | function sha256compression(hin, inp) { 49 | var H[8]; 50 | var a; 51 | var b; 52 | var c; 53 | var d; 54 | var e; 55 | var f; 56 | var g; 57 | var h; 58 | var out[256]; 59 | for (var i=0; i<8; i++) { 60 | H[i] = 0; 61 | for (var j=0; j<32; j++) { 62 | H[i] += hin[i*32+j] << j; 63 | } 64 | } 65 | a=H[0]; 66 | b=H[1]; 67 | c=H[2]; 68 | d=H[3]; 69 | e=H[4]; 70 | f=H[5]; 71 | g=H[6]; 72 | h=H[7]; 73 | var w[64]; 74 | var T1; 75 | var T2; 76 | for (var i=0; i<64; i++) { 77 | if (i<16) { 78 | w[i]=0; 79 | for (var j=0; j<32; j++) { 80 | w[i] += inp[i*32+31-j]<> j) & 1; 109 | } 110 | } 111 | return out; 112 | } 113 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | template ShR(n, r) { 22 | signal input in[n]; 23 | signal output out[n]; 24 | 25 | for (var i=0; i= n) { 27 | out[i] <== 0; 28 | } else { 29 | out[i] <== in[ i+r ]; 30 | } 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "xor3.circom"; 22 | include "rotate.circom"; 23 | include "shift.circom"; 24 | 25 | template SmallSigma(ra, rb, rc) { 26 | signal input in[32]; 27 | signal output out[32]; 28 | var k; 29 | 30 | component rota = RotR(32, ra); 31 | component rotb = RotR(32, rb); 32 | component shrc = ShR(32, rc); 33 | 34 | for (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 | 40 | component xor3 = Xor3(32); 41 | for (k=0; k<32; k++) { 42 | xor3.a[k] <== rota.out[k]; 43 | xor3.b[k] <== rotb.out[k]; 44 | xor3.c[k] <== shrc.out[k]; 45 | } 46 | 47 | for (k=0; k<32; k++) { 48 | out[k] <== xor3.out[k]; 49 | } 50 | } 51 | 52 | template BigSigma(ra, rb, rc) { 53 | signal input in[32]; 54 | signal output out[32]; 55 | var k; 56 | 57 | component rota = RotR(32, ra); 58 | component rotb = RotR(32, rb); 59 | component rotc = RotR(32, rc); 60 | for (k=0; k<32; k++) { 61 | rota.in[k] <== in[k]; 62 | rotb.in[k] <== in[k]; 63 | rotc.in[k] <== in[k]; 64 | } 65 | 66 | component xor3 = Xor3(32); 67 | 68 | for (k=0; k<32; k++) { 69 | xor3.a[k] <== rota.out[k]; 70 | xor3.b[k] <== rotb.out[k]; 71 | xor3.c[k] <== rotc.out[k]; 72 | } 73 | 74 | for (k=0; k<32; k++) { 75 | out[k] <== xor3.out[k]; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "../binsum.circom"; 22 | include "sigma.circom"; 23 | 24 | template SigmaPlus() { 25 | signal input in2[32]; 26 | signal input in7[32]; 27 | signal input in15[32]; 28 | signal input in16[32]; 29 | signal output out[32]; 30 | var k; 31 | 32 | component sigma1 = SmallSigma(17,19,10); 33 | component sigma0 = SmallSigma(7, 18, 3); 34 | for (k=0; k<32; k++) { 35 | sigma1.in[k] <== in2[k]; 36 | sigma0.in[k] <== in15[k]; 37 | } 38 | 39 | component sum = BinSum(32, 4); 40 | for (k=0; k<32; k++) { 41 | sum.in[0][k] <== sigma1.out[k]; 42 | sum.in[1][k] <== in7[k]; 43 | sum.in[2][k] <== sigma0.out[k]; 44 | sum.in[3][k] <== in16[k]; 45 | } 46 | 47 | for (k=0; k<32; k++) { 48 | out[k] <== sum.out[k]; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "../binsum.circom"; 22 | include "sigma.circom"; 23 | include "ch.circom"; 24 | 25 | template T1() { 26 | signal input h[32]; 27 | signal input e[32]; 28 | signal input f[32]; 29 | signal input g[32]; 30 | signal input k[32]; 31 | signal input w[32]; 32 | signal output out[32]; 33 | 34 | var ki; 35 | 36 | component ch = Ch_t(32); 37 | component bigsigma1 = BigSigma(6, 11, 25); 38 | 39 | for (ki=0; ki<32; ki++) { 40 | bigsigma1.in[ki] <== e[ki]; 41 | ch.a[ki] <== e[ki]; 42 | ch.b[ki] <== f[ki]; 43 | ch.c[ki] <== g[ki]; 44 | } 45 | 46 | component sum = BinSum(32, 5); 47 | for (ki=0; ki<32; ki++) { 48 | sum.in[0][ki] <== h[ki]; 49 | sum.in[1][ki] <== bigsigma1.out[ki]; 50 | sum.in[2][ki] <== ch.out[ki]; 51 | sum.in[3][ki] <== k[ki]; 52 | sum.in[4][ki] <== w[ki]; 53 | } 54 | 55 | for (ki=0; ki<32; ki++) { 56 | out[ki] <== sum.out[ki]; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "../binsum.circom"; 22 | include "sigma.circom"; 23 | include "maj.circom"; 24 | 25 | template T2() { 26 | signal input a[32]; 27 | signal input b[32]; 28 | signal input c[32]; 29 | signal output out[32]; 30 | var k; 31 | 32 | component bigsigma0 = BigSigma(2, 13, 22); 33 | component maj = Maj_t(32); 34 | for (k=0; k<32; k++) { 35 | bigsigma0.in[k] <== a[k]; 36 | maj.a[k] <== a[k]; 37 | maj.b[k] <== b[k]; 38 | maj.c[k] <== c[k]; 39 | } 40 | 41 | component sum = BinSum(32, 2); 42 | 43 | for (k=0; k<32; k++) { 44 | sum.in[0][k] <== bigsigma0.out[k]; 45 | sum.in[1][k] <== maj.out[k]; 46 | } 47 | 48 | for (k=0; k<32; k++) { 49 | out[k] <== sum.out[k]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 33 | 34 | template Xor3(n) { 35 | signal input a[n]; 36 | signal input b[n]; 37 | signal input c[n]; 38 | signal output out[n]; 39 | signal mid[n]; 40 | 41 | for (var k=0; k. 18 | */ 19 | pragma circom 2.0.0; 20 | 21 | include "compconstant.circom"; 22 | 23 | template Sign() { 24 | signal input in[254]; 25 | signal output sign; 26 | 27 | component comp = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808); 28 | 29 | var i; 30 | 31 | for (i=0; i<254; i++) { 32 | comp.in[i] <== in[i]; 33 | } 34 | 35 | sign <== comp.out; 36 | } 37 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "../mimc.circom"; 22 | 23 | 24 | /* 25 | Hash1 = H(1 | key | value) 26 | */ 27 | 28 | template SMTHash1() { 29 | signal input key; 30 | signal input value; 31 | signal output out; 32 | 33 | component h = MultiMiMC7(2, 91); // Constant 34 | h.in[0] <== key; 35 | h.in[1] <== value; 36 | h.k <== 1; 37 | 38 | out <== h.out; 39 | } 40 | 41 | /* 42 | This component is used to create the 2 nodes. 43 | 44 | Hash2 = H(Hl | Hr) 45 | */ 46 | 47 | template SMTHash2() { 48 | signal input L; 49 | signal input R; 50 | signal output out; 51 | 52 | component h = MultiMiMC7(2, 91); // Constant 53 | h.in[0] <== L; 54 | h.in[1] <== R; 55 | h.k <== 0; 56 | 57 | out <== h.out; 58 | } 59 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 20 | 21 | include "../poseidon.circom"; 22 | 23 | 24 | /* 25 | Hash1 = H(1 | key | value) 26 | */ 27 | 28 | template SMTHash1() { 29 | signal input key; 30 | signal input value; 31 | signal output out; 32 | 33 | component h = Poseidon(3); // Constant 34 | h.inputs[0] <== key; 35 | h.inputs[1] <== value; 36 | h.inputs[2] <== 1; 37 | 38 | out <== h.out; 39 | } 40 | 41 | /* 42 | This component is used to create the 2 nodes. 43 | 44 | Hash2 = H(Hl | Hr) 45 | */ 46 | 47 | template SMTHash2() { 48 | signal input L; 49 | signal input R; 50 | signal output out; 51 | 52 | component h = Poseidon(2); // Constant 53 | h.inputs[0] <== L; 54 | h.inputs[1] <== R; 55 | 56 | out <== h.out; 57 | } 58 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 76 | 77 | template SMTLevIns(nLevels) { 78 | signal input enabled; 79 | signal input siblings[nLevels]; 80 | signal output levIns[nLevels]; 81 | signal done[nLevels-1]; // Indicates if the insLevel has aready been detected. 82 | 83 | var i; 84 | 85 | component isZero[nLevels]; 86 | 87 | for (i=0; i0; i--) { 98 | levIns[i] <== (1-done[i])*(1-isZero[i-1].out); 99 | done[i-1] <== levIns[i] + done[i]; 100 | } 101 | 102 | levIns[0] <== (1-done[0]); 103 | } 104 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 42 | 43 | 44 | template SMTProcessorLevel() { 45 | signal input st_top; 46 | signal input st_old0; 47 | signal input st_bot; 48 | signal input st_new1; 49 | signal input st_na; 50 | signal input st_upd; 51 | 52 | signal output oldRoot; 53 | signal output newRoot; 54 | signal input sibling; 55 | signal input old1leaf; 56 | signal input new1leaf; 57 | signal input newlrbit; 58 | signal input oldChild; 59 | signal input newChild; 60 | 61 | signal aux[4]; 62 | 63 | component oldProofHash = SMTHash2(); 64 | component newProofHash = SMTHash2(); 65 | 66 | component oldSwitcher = Switcher(); 67 | component newSwitcher = Switcher(); 68 | 69 | // Old side 70 | 71 | oldSwitcher.L <== oldChild; 72 | oldSwitcher.R <== sibling; 73 | 74 | oldSwitcher.sel <== newlrbit; 75 | oldProofHash.L <== oldSwitcher.outL; 76 | oldProofHash.R <== oldSwitcher.outR; 77 | 78 | aux[0] <== old1leaf * (st_bot + st_new1 + st_upd); 79 | oldRoot <== aux[0] + oldProofHash.out * st_top; 80 | 81 | // New side 82 | 83 | aux[1] <== newChild * ( st_top + st_bot); 84 | newSwitcher.L <== aux[1] + new1leaf*st_new1; 85 | 86 | aux[2] <== sibling*st_top; 87 | newSwitcher.R <== aux[2] + old1leaf*st_new1; 88 | 89 | newSwitcher.sel <== newlrbit; 90 | newProofHash.L <== newSwitcher.outL; 91 | newProofHash.R <== newSwitcher.outR; 92 | 93 | aux[3] <== newProofHash.out * (st_top + st_bot + st_new1); 94 | newRoot <== aux[3] + new1leaf * (st_old0 + st_upd); 95 | } 96 | -------------------------------------------------------------------------------- /circuits/smt/smtverifier.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 | SMTVerifier is a component to verify inclusion/exclusion of an element in the tree 23 | 24 | 25 | fnc: 0 -> VERIFY INCLUSION 26 | 1 -> VERIFY NOT INCLUSION 27 | 28 | */ 29 | pragma circom 2.0.0; 30 | 31 | 32 | include "../gates.circom"; 33 | include "../bitify.circom"; 34 | include "../comparators.circom"; 35 | include "../switcher.circom"; 36 | include "smtlevins.circom"; 37 | include "smtverifierlevel.circom"; 38 | include "smtverifiersm.circom"; 39 | include "smthash_poseidon.circom"; 40 | 41 | template SMTVerifier(nLevels) { 42 | signal input enabled; 43 | signal input root; 44 | signal input siblings[nLevels]; 45 | signal input oldKey; 46 | signal input oldValue; 47 | signal input isOld0; 48 | signal input key; 49 | signal input value; 50 | signal input fnc; 51 | 52 | var i; 53 | 54 | component hash1Old = SMTHash1(); 55 | hash1Old.key <== oldKey; 56 | hash1Old.value <== oldValue; 57 | 58 | component hash1New = SMTHash1(); 59 | hash1New.key <== key; 60 | hash1New.value <== value; 61 | 62 | component n2bOld = Num2Bits_strict(); 63 | component n2bNew = Num2Bits_strict(); 64 | 65 | n2bOld.in <== oldKey; 66 | n2bNew.in <== key; 67 | 68 | component smtLevIns = SMTLevIns(nLevels); 69 | for (i=0; i. 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 | pragma circom 2.0.0; 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 | -------------------------------------------------------------------------------- /circuits/smt/smtverifiersm.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 | Each level in the SMTVerifier has a state. 22 | 23 | This is the state machine. 24 | 25 | The signals are 26 | 27 | levIns: 1 if we are in the level where the insertion should happen 28 | xor: 1 if the bitKey of the old and new keys are different in this level 29 | is0: Input that indicates that the oldKey is 0 30 | fnc: 0 -> VERIFY INCLUSION 31 | 1 -> VERIFY NOT INCLUSION 32 | 33 | err state is not a state itself. It's a lack of state. 34 | 35 | The end of the last level will have to be `na` 36 | 37 | levIns=0 any 38 | ┌────┐ ┌────┐ 39 | │ │ │ │ 40 | │ ▼ levIns=1 ▼ │ 41 | │ ########### is0=1 ########### ########### │ 42 | │ # # fnc=1 # # any # # │ 43 | └──# top # ─────────────────────▶# i0 #───────────────▶# na #──┘ 44 | ## ## ──────────┐ ## ## ┌───────▶## ## 45 | ########─────────────┐│ ######### │┌────────▶######### 46 | ││ levIns=1 ││ 47 | ││ is0=0 ########### ││ 48 | ││ fnc=1 # # any│ 49 | │└──────────▶ # iold #────────┘│ 50 | │ ## ## │ 51 | │ ######### │ 52 | │ │ 53 | │ levIns=1 ########### │ 54 | │ fnc=0 # # any 55 | └────────────▶# inew #─────────┘ 56 | ## ## 57 | ######### 58 | 59 | */ 60 | pragma circom 2.0.0; 61 | 62 | 63 | template SMTVerifierSM() { 64 | signal input is0; 65 | signal input levIns; 66 | signal input fnc; 67 | 68 | signal input prev_top; 69 | signal input prev_i0; 70 | signal input prev_iold; 71 | signal input prev_inew; 72 | signal input prev_na; 73 | 74 | signal output st_top; 75 | signal output st_i0; 76 | signal output st_iold; 77 | signal output st_inew; 78 | signal output st_na; 79 | 80 | signal prev_top_lev_ins; 81 | signal prev_top_lev_ins_fnc; 82 | 83 | prev_top_lev_ins <== prev_top * levIns; 84 | prev_top_lev_ins_fnc <== prev_top_lev_ins*fnc; // prev_top * levIns * fnc 85 | 86 | // st_top = prev_top * (1-levIns) 87 | // = + prev_top 88 | // - prev_top * levIns 89 | st_top <== prev_top - prev_top_lev_ins; 90 | 91 | // st_inew = prev_top * levIns * (1-fnc) 92 | // = + prev_top * levIns 93 | // - prev_top * levIns * fnc 94 | st_inew <== prev_top_lev_ins - prev_top_lev_ins_fnc; 95 | 96 | // st_iold = prev_top * levIns * (1-is0)*fnc 97 | // = + prev_top * levIns * fnc 98 | // - prev_top * levIns * fnc * is0 99 | st_iold <== prev_top_lev_ins_fnc * (1 - is0); 100 | 101 | // st_i0 = prev_top * levIns * is0 102 | // = + prev_top * levIns * is0 103 | st_i0 <== prev_top_lev_ins * is0; 104 | 105 | st_na <== prev_na + prev_inew + prev_iold + prev_i0; 106 | } 107 | -------------------------------------------------------------------------------- /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 | pragma circom 2.0.0; 29 | 30 | template Switcher() { 31 | signal input sel; 32 | signal input L; 33 | signal input R; 34 | signal output outL; 35 | signal output outR; 36 | 37 | signal aux; 38 | 39 | aux <== (R-L)*sel; // We create aux in order to have only one multiplication 40 | outL <== aux + L; 41 | outR <== -aux + R; 42 | } 43 | -------------------------------------------------------------------------------- /doc/root_transfer.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iden3/circomlib/35e54ea21da3e8762557234298dbb553c175ea8d/doc/root_transfer.monopic -------------------------------------------------------------------------------- /doc/smt_diagram_0.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iden3/circomlib/35e54ea21da3e8762557234298dbb553c175ea8d/doc/smt_diagram_0.monopic -------------------------------------------------------------------------------- /doc/smt_diagram_1.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iden3/circomlib/35e54ea21da3e8762557234298dbb553c175ea8d/doc/smt_diagram_1.monopic -------------------------------------------------------------------------------- /doc/smt_hash.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iden3/circomlib/35e54ea21da3e8762557234298dbb553c175ea8d/doc/smt_hash.monopic -------------------------------------------------------------------------------- /doc/smt_levins.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iden3/circomlib/35e54ea21da3e8762557234298dbb553c175ea8d/doc/smt_levins.monopic -------------------------------------------------------------------------------- /doc/smt_sm.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iden3/circomlib/35e54ea21da3e8762557234298dbb553c175ea8d/doc/smt_sm.monopic -------------------------------------------------------------------------------- /doc/smt_verifier_sm.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iden3/circomlib/35e54ea21da3e8762557234298dbb553c175ea8d/doc/smt_verifier_sm.monopic -------------------------------------------------------------------------------- /doc/voting.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iden3/circomlib/35e54ea21da3e8762557234298dbb553c175ea8d/doc/voting.monopic -------------------------------------------------------------------------------- /doc/window.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iden3/circomlib/35e54ea21da3e8762557234298dbb553c175ea8d/doc/window.monopic -------------------------------------------------------------------------------- /doc/window_chain.monopic: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iden3/circomlib/35e54ea21da3e8762557234298dbb553c175ea8d/doc/window_chain.monopic -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "circomlib", 3 | "version": "2.0.5", 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": "LGPL-3.0", 26 | "devDependencies": { 27 | "@noble/hashes": "^1.7.1", 28 | "chai": "^4.3.4", 29 | "circom_tester": "0.0.21", 30 | "circomlibjs": "^0.1.7", 31 | "mocha": "^11.1.0" 32 | } 33 | } -------------------------------------------------------------------------------- /test/aliascheck.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | 4 | const assert = chai.assert; 5 | 6 | const Scalar = require("ffjavascript").Scalar; 7 | const F1Field = require("ffjavascript").F1Field; 8 | const utils = require("ffjavascript").utils; 9 | const q = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); 10 | const F = new F1Field(q); 11 | 12 | const wasm_tester = require("circom_tester").wasm; 13 | 14 | function print(circuit, w, s) { 15 | console.log(s + ": " + w[circuit.getSignalIdx(s)]); 16 | } 17 | 18 | function getBits(v, n) { 19 | const res = []; 20 | for (let i=0; i { 36 | 37 | cir = await wasm_tester(path.join(__dirname, "circuits", "aliascheck_test.circom")); 38 | }); 39 | 40 | it("Satisfy the aliastest 0", async () => { 41 | const inp = getBits(0, 254); 42 | await cir.calculateWitness({in: inp}, true); 43 | }); 44 | 45 | it("Satisfy the aliastest 3", async () => { 46 | const inp = getBits(3, 254); 47 | await cir.calculateWitness({in: inp}, true); 48 | }); 49 | 50 | it("Satisfy the aliastest q-1", async () => { 51 | const inp = getBits(F.e(-1), 254); 52 | // console.log(JSON.stringify(utils.stringifyBigInts(inp))); 53 | await cir.calculateWitness({in: inp}, true); 54 | }); 55 | 56 | it("Should not satisfy an input of q", async () => { 57 | const inp = getBits(q, 254); 58 | try { 59 | await cir.calculateWitness({in: inp}, true); 60 | assert(false); 61 | } catch(err) { 62 | assert(err.message.includes("Assert Failed")); 63 | } 64 | }); 65 | 66 | it("Should not satisfy all ones", async () => { 67 | 68 | const inp = getBits(Scalar.sub(Scalar.shl(1, 254) , 1) , 254); 69 | try { 70 | await cir.calculateWitness({in: inp}, true); 71 | assert(false); 72 | } catch(err) { 73 | assert(err.message.includes("Assert Failed")); 74 | } 75 | }); 76 | 77 | }); 78 | -------------------------------------------------------------------------------- /test/babyjub.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | 4 | const { blake512 } = require('@noble/hashes/blake1'); 5 | const buildEddsa = require("circomlibjs").buildEddsa; 6 | 7 | const assert = chai.assert; 8 | 9 | const wasm_tester = require("circom_tester").wasm; 10 | const utils = require("ffjavascript").utils; 11 | const Scalar = require("ffjavascript").Scalar; 12 | 13 | describe("Baby Jub test", function () { 14 | let eddsa; 15 | let F; 16 | let circuitAdd; 17 | let circuitTest; 18 | let circuitPbk; 19 | 20 | this.timeout(100000); 21 | 22 | before( async() => { 23 | 24 | eddsa = await buildEddsa(); 25 | F = eddsa.F; 26 | 27 | circuitAdd = await wasm_tester(path.join(__dirname, "circuits", "babyadd_tester.circom")); 28 | 29 | circuitTest = await wasm_tester(path.join(__dirname, "circuits", "babycheck_test.circom")); 30 | 31 | circuitPbk = await wasm_tester(path.join(__dirname, "circuits", "babypbk_test.circom")); 32 | }); 33 | 34 | it("Should add point (0,1) and (0,1)", async () => { 35 | 36 | const input={ 37 | x1: 0, 38 | y1: 1, 39 | x2: 0, 40 | y2: 1 41 | }; 42 | 43 | const w = await circuitAdd.calculateWitness(input, true); 44 | 45 | await circuitAdd.assertOut(w, {xout: 0, yout: 1}); 46 | }); 47 | 48 | it("Should add 2 same numbers", async () => { 49 | 50 | const input={ 51 | x1: 17777552123799933955779906779655732241715742912184938656739573121738514868268n, 52 | y1: 2626589144620713026669568689430873010625803728049924121243784502389097019475n, 53 | x2: 17777552123799933955779906779655732241715742912184938656739573121738514868268n, 54 | y2: 2626589144620713026669568689430873010625803728049924121243784502389097019475n 55 | }; 56 | 57 | const w = await circuitAdd.calculateWitness(input, true); 58 | 59 | await circuitAdd.assertOut(w, { 60 | xout: 6890855772600357754907169075114257697580319025794532037257385534741338397365n, 61 | yout: 4338620300185947561074059802482547481416142213883829469920100239455078257889n 62 | }); 63 | 64 | }); 65 | 66 | it("Should add 2 different numbers", async () => { 67 | 68 | const input={ 69 | x1: 17777552123799933955779906779655732241715742912184938656739573121738514868268n, 70 | y1: 2626589144620713026669568689430873010625803728049924121243784502389097019475n, 71 | x2: 16540640123574156134436876038791482806971768689494387082833631921987005038935n, 72 | y2: 20819045374670962167435360035096875258406992893633759881276124905556507972311n 73 | }; 74 | 75 | const w = await circuitAdd.calculateWitness(input, true); 76 | 77 | await circuitAdd.assertOut(w, { 78 | xout: 7916061937171219682591368294088513039687205273691143098332585753343424131937n, 79 | yout: 14035240266687799601661095864649209771790948434046947201833777492504781204499n 80 | }); 81 | 82 | }); 83 | 84 | it("Should check (0,1) is a valid point", async() => { 85 | const w = await circuitTest.calculateWitness({x: 0, y:1}, true); 86 | 87 | await circuitTest.checkConstraints(w); 88 | }); 89 | 90 | it("Should check (1,0) is an invalid point", async() => { 91 | try { 92 | await circuitTest.calculateWitness({x: 1, y: 0}, true); 93 | assert(false, "Should be a valid point"); 94 | } catch(err) { 95 | assert(err.message.includes("Assert Failed")); 96 | } 97 | }); 98 | 99 | it("Should extract the public key from the private one", async () => { 100 | 101 | const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex"); 102 | const pvk = eddsa.pruneBuffer(blake512(rawpvk).slice(0,32)); 103 | const S = Scalar.shr(utils.leBuff2int(pvk), 3); 104 | 105 | const A = eddsa.prv2pub(rawpvk); 106 | 107 | const input = { 108 | in : S 109 | }; 110 | 111 | const w = await circuitPbk.calculateWitness(input, true); 112 | 113 | await circuitPbk.assertOut(w, {Ax : F.toObject(A[0]), Ay: F.toObject(A[1])}); 114 | 115 | await circuitPbk.checkConstraints(w); 116 | }); 117 | 118 | }); 119 | -------------------------------------------------------------------------------- /test/binsub.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | const Scalar = require("ffjavascript").Scalar; 4 | const wasm_tester = require("circom_tester").wasm; 5 | 6 | function print(circuit, w, s) { 7 | console.log(s + ": " + w[circuit.getSignalIdx(s)]); 8 | } 9 | 10 | async function checkSub(_a,_b, circuit) { 11 | let a=Scalar.e(_a); 12 | let b=Scalar.e(_b); 13 | if (Scalar.lt(a, 0)) a = Scalar.add(a, Scalar.shl(1, 16)); 14 | if (Scalar.lt(b, 0)) b = Scalar.add(b, Scalar.shl(1, 16)); 15 | const w = await circuit.calculateWitness({a: a, b: b}, true); 16 | 17 | let res = Scalar.sub(a, b); 18 | if (Scalar.lt(res, 0)) res = Scalar.add(res, Scalar.shl(1, 16)); 19 | 20 | await circuit.assertOut(w, {out: res}); 21 | } 22 | 23 | describe("BinSub test", function () { 24 | 25 | this.timeout(100000); 26 | 27 | let circuit; 28 | before( async() => { 29 | circuit = await wasm_tester(path.join(__dirname, "circuits", "binsub_test.circom")); 30 | }); 31 | 32 | it("Should check variuos ege cases", async () => { 33 | await checkSub(0,0, circuit); 34 | await checkSub(1,0, circuit); 35 | await checkSub(-1,0, circuit); 36 | await checkSub(2,1, circuit); 37 | await checkSub(2,2, circuit); 38 | await checkSub(2,3, circuit); 39 | await checkSub(2,-1, circuit); 40 | await checkSub(2,-2, circuit); 41 | await checkSub(2,-3, circuit); 42 | await checkSub(-2,-3, circuit); 43 | await checkSub(-2,-2, circuit); 44 | await checkSub(-2,-1, circuit); 45 | await checkSub(-2,0, circuit); 46 | await checkSub(-2,1, circuit); 47 | await checkSub(-2,2, circuit); 48 | await checkSub(-2,3, circuit); 49 | }); 50 | 51 | 52 | }); 53 | -------------------------------------------------------------------------------- /test/binsum.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | 4 | const wasm_tester = require("circom_tester").wasm; 5 | 6 | const F1Field = require("ffjavascript").F1Field; 7 | const Scalar = require("ffjavascript").Scalar; 8 | exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); 9 | const Fr = new F1Field(exports.p); 10 | 11 | const assert = chai.assert; 12 | 13 | describe("Binary sum test", function () { 14 | this.timeout(100000000); 15 | 16 | it("Should create a constant circuit", async () => { 17 | const circuit = await wasm_tester(path.join(__dirname, "circuits", "constants_test.circom")); 18 | await circuit.loadConstraints(); 19 | assert.equal(circuit.nVars, 2); 20 | assert.equal(circuit.constraints.length, 1); 21 | 22 | const witness = await circuit.calculateWitness({ "in": Fr.toString(Fr.e("0xd807aa98"))}, true); 23 | 24 | assert(Fr.eq(Fr.e(witness[0]),Fr.e(1))); 25 | assert(Fr.eq(Fr.e(witness[1]),Fr.e("0xd807aa98"))); 26 | }); 27 | it("Should create a sum circuit", async () => { 28 | const circuit = await wasm_tester(path.join(__dirname, "circuits", "sum_test.circom")); 29 | await circuit.loadConstraints(); 30 | 31 | // assert.equal(circuit.constraints.length, 97); // 32 (in1) + 32(in2) + 32(out) + 1 (carry) with --O2 32 | assert.equal(circuit.constraints.length, 101); // 32 (in1) + 32(in2) + 32(out) + 1 (carry) + 4 linear with --O1 33 | 34 | const witness = await circuit.calculateWitness({ "a": "111", "b": "222" }, true); 35 | 36 | assert(Fr.eq(Fr.e(witness[0]),Fr.e(1))); 37 | assert(Fr.eq(Fr.e(witness[1]),Fr.e("333"))); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /test/circuits/aliascheck_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | include "../../circuits/aliascheck.circom"; 3 | 4 | component main = AliasCheck(); 5 | -------------------------------------------------------------------------------- /test/circuits/babyadd_tester.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | include "../../circuits/babyjub.circom"; 3 | 4 | component main = BabyAdd(); 5 | -------------------------------------------------------------------------------- /test/circuits/babycheck_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | include "../../circuits/babyjub.circom"; 3 | 4 | component main = BabyCheck(); 5 | -------------------------------------------------------------------------------- /test/circuits/babypbk_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | include "../../circuits/babyjub.circom"; 3 | 4 | component main = BabyPbk(); 5 | -------------------------------------------------------------------------------- /test/circuits/binsub_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/bitify.circom"; 4 | include "../../circuits/binsub.circom"; 5 | 6 | template A() { 7 | signal input a; //private 8 | signal input b; 9 | signal output out; 10 | 11 | var i; 12 | 13 | component n2ba = Num2Bits(16); 14 | component n2bb = Num2Bits(16); 15 | component sub = BinSub(16); 16 | component b2n = Bits2Num(16); 17 | 18 | n2ba.in <== a; 19 | n2bb.in <== b; 20 | 21 | for (i=0; i<16; i++) { 22 | sub.in[0][i] <== n2ba.out[i]; 23 | sub.in[1][i] <== n2bb.out[i]; 24 | } 25 | 26 | for (i=0; i<16; i++) { 27 | b2n.in[i] <== sub.out[i]; 28 | } 29 | 30 | out <== b2n.out; 31 | } 32 | 33 | component main = A(); 34 | -------------------------------------------------------------------------------- /test/circuits/constants_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/sha256/constants.circom"; 4 | 5 | template A() { 6 | signal input in; 7 | component h0; 8 | h0 = K(8); 9 | 10 | var lc = 0; 11 | var e = 1; 12 | for (var i=0; i<32; i++) { 13 | lc = lc + e*h0.out[i]; 14 | e *= 2; 15 | } 16 | 17 | lc === in; 18 | } 19 | 20 | component main {public [in]} = A(); 21 | -------------------------------------------------------------------------------- /test/circuits/eddsa_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/eddsa.circom"; 4 | 5 | component main = EdDSAVerifier(80); 6 | -------------------------------------------------------------------------------- /test/circuits/eddsamimc_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/eddsamimc.circom"; 4 | 5 | component main = EdDSAMiMCVerifier(); 6 | -------------------------------------------------------------------------------- /test/circuits/eddsaposeidon_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/eddsaposeidon.circom"; 4 | 5 | component main = EdDSAPoseidonVerifier(); 6 | -------------------------------------------------------------------------------- /test/circuits/edwards2montgomery.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/montgomery.circom"; 4 | 5 | component main = Edwards2Montgomery(); 6 | -------------------------------------------------------------------------------- /test/circuits/escalarmul_min_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/escalarmul.circom"; 4 | 5 | 6 | template Main() { 7 | signal input in[256]; 8 | signal output out[2]; 9 | 10 | var i; 11 | 12 | var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 16950150798460657717958625567821834550301663161624707787222815936182638968203]; 13 | 14 | component escalarMul = EscalarMul(256, base); 15 | 16 | escalarMul.inp[0] <== 0; 17 | escalarMul.inp[1] <== 1; 18 | 19 | for (i=0; i<256; i++) { 20 | in[i] ==> escalarMul.in[i]; 21 | } 22 | 23 | escalarMul.out[0] ==> out[0]; 24 | escalarMul.out[1] ==> out[1]; 25 | } 26 | 27 | component main = Main(); 28 | -------------------------------------------------------------------------------- /test/circuits/escalarmul_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/escalarmul.circom"; 4 | include "../../circuits/bitify.circom"; 5 | 6 | 7 | template Main() { 8 | signal input in; 9 | signal output out[2]; 10 | 11 | var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 12 | 16950150798460657717958625567821834550301663161624707787222815936182638968203]; 13 | 14 | 15 | component n2b = Num2Bits(253); 16 | component escalarMul = EscalarMul(253, base); 17 | 18 | escalarMul.inp[0] <== 0; 19 | escalarMul.inp[1] <== 1; 20 | 21 | var i; 22 | 23 | in ==> n2b.in; 24 | 25 | for (i=0; i<253; i++) { 26 | n2b.out[i] ==> escalarMul.in[i]; 27 | } 28 | 29 | escalarMul.out[0] ==> out[0]; 30 | escalarMul.out[1] ==> out[1]; 31 | } 32 | 33 | component main = Main(); 34 | -------------------------------------------------------------------------------- /test/circuits/escalarmul_test_min.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/escalarmul.circom"; 4 | 5 | 6 | template Main() { 7 | signal input in[256]; 8 | signal output out[2]; 9 | 10 | var i; 11 | 12 | var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 13 | 16950150798460657717958625567821834550301663161624707787222815936182638968203]; 14 | 15 | component escalarMul = EscalarMul(256, base); 16 | 17 | escalarMul.inp[0] <== 0; 18 | escalarMul.inp[1] <== 1; 19 | 20 | for (i=0; i<256; i++) { 21 | in[i] ==> escalarMul.in[i]; 22 | } 23 | 24 | escalarMul.out[0] ==> out[0]; 25 | escalarMul.out[1] ==> out[1]; 26 | } 27 | 28 | component main = Main(); 29 | -------------------------------------------------------------------------------- /test/circuits/escalarmulany_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/escalarmulany.circom"; 4 | include "../../circuits/bitify.circom"; 5 | 6 | template Main() { 7 | signal input e; 8 | signal input p[2]; 9 | signal output out[2]; 10 | 11 | component n2b = Num2Bits(253); 12 | component escalarMulAny = EscalarMulAny(253); 13 | 14 | escalarMulAny.p[0] <== p[0]; 15 | escalarMulAny.p[1] <== p[1]; 16 | 17 | var i; 18 | 19 | e ==> n2b.in; 20 | 21 | for (i=0; i<253; i++) { 22 | n2b.out[i] ==> escalarMulAny.e[i]; 23 | } 24 | 25 | escalarMulAny.out[0] ==> out[0]; 26 | escalarMulAny.out[1] ==> out[1]; 27 | } 28 | 29 | component main = Main(); 30 | 31 | -------------------------------------------------------------------------------- /test/circuits/escalarmulfix_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/escalarmulfix.circom"; 4 | include "../../circuits/bitify.circom"; 5 | 6 | 7 | template Main() { 8 | signal input e; 9 | signal output out[2]; 10 | 11 | var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 12 | 16950150798460657717958625567821834550301663161624707787222815936182638968203]; 13 | 14 | 15 | component n2b = Num2Bits(253); 16 | component escalarMul = EscalarMulFix(253, base); 17 | 18 | var i; 19 | 20 | e ==> n2b.in; 21 | 22 | for (i=0; i<253; i++) { 23 | n2b.out[i] ==> escalarMul.e[i]; 24 | } 25 | 26 | escalarMul.out[0] ==> out[0]; 27 | escalarMul.out[1] ==> out[1]; 28 | } 29 | 30 | component main = Main(); 31 | 32 | -------------------------------------------------------------------------------- /test/circuits/escalarmulw4table.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/escalarmulw4table.circom"; 4 | 5 | 6 | 7 | 8 | template Main() { 9 | signal output out[16][2]; 10 | var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 11 | 16950150798460657717958625567821834550301663161624707787222815936182638968203]; 12 | 13 | var escalarMul[16][2] = EscalarMulW4Table(base, 0); 14 | for (var i=0; i<16; i++) { 15 | out[i][0] <== escalarMul[i][0]; 16 | out[i][1] <== escalarMul[i][1]; 17 | } 18 | } 19 | 20 | component main = Main(); 21 | -------------------------------------------------------------------------------- /test/circuits/escalarmulw4table_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/escalarmulw4table.circom"; 4 | 5 | 6 | template Main() { 7 | signal input in; 8 | signal output out[16][2]; 9 | var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 10 | 16950150798460657717958625567821834550301663161624707787222815936182638968203]; 11 | 12 | var escalarMul[16][2] = EscalarMulW4Table(base, 0); 13 | for (var i=0; i<16; i++) { 14 | out[i][0] <== escalarMul[i][0]*in; 15 | out[i][1] <== escalarMul[i][1]*in; 16 | } 17 | } 18 | 19 | component main = Main(); 20 | -------------------------------------------------------------------------------- /test/circuits/escalarmulw4table_test3.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/escalarmulw4table.circom"; 4 | 5 | 6 | template Main() { 7 | signal input in; 8 | signal output out[16][2]; 9 | var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553, 10 | 16950150798460657717958625567821834550301663161624707787222815936182638968203]; 11 | 12 | var escalarMul[16][2] = EscalarMulW4Table(base, 3); 13 | for (var i=0; i<16; i++) { 14 | out[i][0] <== escalarMul[i][0]*in; 15 | out[i][1] <== escalarMul[i][1]*in; 16 | } 17 | } 18 | 19 | component main = Main(); 20 | -------------------------------------------------------------------------------- /test/circuits/greatereqthan.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/comparators.circom"; 4 | 5 | component main = GreaterEqThan(32); 6 | -------------------------------------------------------------------------------- /test/circuits/greaterthan.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/comparators.circom"; 4 | 5 | component main = GreaterThan(32); 6 | -------------------------------------------------------------------------------- /test/circuits/isequal.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/comparators.circom"; 4 | 5 | component main = IsEqual(); 6 | -------------------------------------------------------------------------------- /test/circuits/iszero.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/comparators.circom"; 4 | 5 | component main = IsZero(); 6 | -------------------------------------------------------------------------------- /test/circuits/lesseqthan.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/comparators.circom"; 4 | 5 | component main = LessEqThan(32); 6 | -------------------------------------------------------------------------------- /test/circuits/lessthan.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/comparators.circom"; 4 | 5 | component main = LessThan(32); 6 | -------------------------------------------------------------------------------- /test/circuits/mimc_sponge_hash_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/mimcsponge.circom"; 4 | 5 | component main = MiMCSponge(2, 220, 3); 6 | -------------------------------------------------------------------------------- /test/circuits/mimc_sponge_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/mimcsponge.circom"; 4 | 5 | component main = MiMCFeistel(220); 6 | -------------------------------------------------------------------------------- /test/circuits/mimc_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/mimc.circom"; 4 | 5 | component main = MiMC7(91); 6 | -------------------------------------------------------------------------------- /test/circuits/montgomery2edwards.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/montgomery.circom"; 4 | 5 | component main = Montgomery2Edwards(); 6 | -------------------------------------------------------------------------------- /test/circuits/montgomeryadd.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/montgomery.circom"; 4 | 5 | component main = MontgomeryAdd(); 6 | -------------------------------------------------------------------------------- /test/circuits/montgomerydouble.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/montgomery.circom"; 4 | 5 | component main = MontgomeryDouble(); 6 | -------------------------------------------------------------------------------- /test/circuits/mux1_1.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/mux1.circom"; 4 | include "../../circuits/bitify.circom"; 5 | 6 | 7 | template Constants() { 8 | var i; 9 | signal output out[2]; 10 | 11 | out[0] <== 37; 12 | out[1] <== 47; 13 | } 14 | 15 | template Main() { 16 | var i; 17 | signal input selector;//private 18 | signal output out; 19 | 20 | component mux = Mux1(); 21 | component n2b = Num2Bits(1); 22 | component cst = Constants(); 23 | 24 | selector ==> n2b.in; 25 | n2b.out[0] ==> mux.s; 26 | for (i=0; i<2; i++) { 27 | cst.out[i] ==> mux.c[i]; 28 | } 29 | 30 | mux.out ==> out; 31 | } 32 | 33 | component main = Main(); 34 | -------------------------------------------------------------------------------- /test/circuits/mux2_1.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/mux2.circom"; 4 | include "../../circuits/bitify.circom"; 5 | 6 | 7 | template Constants() { 8 | var i; 9 | signal output out[4]; 10 | 11 | out[0] <== 37; 12 | out[1] <== 47; 13 | out[2] <== 53; 14 | out[3] <== 71; 15 | } 16 | 17 | template Main() { 18 | var i; 19 | signal input selector;//private 20 | signal output out; 21 | 22 | component mux = Mux2(); 23 | component n2b = Num2Bits(2); 24 | component cst = Constants(); 25 | 26 | selector ==> n2b.in; 27 | for (i=0; i<2; i++) { 28 | n2b.out[i] ==> mux.s[i]; 29 | } 30 | for (i=0; i<4; i++) { 31 | cst.out[i] ==> mux.c[i]; 32 | } 33 | 34 | mux.out ==> out; 35 | } 36 | 37 | component main = Main(); 38 | -------------------------------------------------------------------------------- /test/circuits/mux3_1.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/mux3.circom"; 4 | include "../../circuits/bitify.circom"; 5 | 6 | 7 | template Constants() { 8 | var i; 9 | signal output out[8]; 10 | 11 | out[0] <== 37; 12 | out[1] <== 47; 13 | out[2] <== 53; 14 | out[3] <== 71; 15 | out[4] <== 89; 16 | out[5] <== 107; 17 | out[6] <== 163; 18 | out[7] <== 191; 19 | } 20 | 21 | template Main() { 22 | var i; 23 | signal input selector;//private 24 | signal output out; 25 | 26 | component mux = Mux3(); 27 | component n2b = Num2Bits(3); 28 | component cst = Constants(); 29 | 30 | selector ==> n2b.in; 31 | for (i=0; i<3; i++) { 32 | n2b.out[i] ==> mux.s[i]; 33 | } 34 | for (i=0; i<8; i++) { 35 | cst.out[i] ==> mux.c[i]; 36 | } 37 | 38 | mux.out ==> out; 39 | } 40 | 41 | component main = Main(); 42 | -------------------------------------------------------------------------------- /test/circuits/mux4_1.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/mux4.circom"; 4 | include "../../circuits/bitify.circom"; 5 | 6 | 7 | template Constants() { 8 | var i; 9 | signal output out[16]; 10 | 11 | out[0] <== 123; 12 | out[1] <== 456; 13 | out[2] <== 789; 14 | out[3] <== 012; 15 | out[4] <== 111; 16 | out[5] <== 222; 17 | out[6] <== 333; 18 | out[7] <== 4546; 19 | out[8] <== 134523; 20 | out[9] <== 44356; 21 | out[10] <== 15623; 22 | out[11] <== 4566; 23 | out[12] <== 1223; 24 | out[13] <== 4546; 25 | out[14] <== 4256; 26 | out[15] <== 4456; 27 | 28 | /* 29 | for (i=0;i<16; i++) { 30 | out[i] <== i*2+100; 31 | } 32 | */ 33 | 34 | } 35 | 36 | template Main() { 37 | var i; 38 | signal input selector;//private 39 | signal output out; 40 | 41 | component mux = Mux4(); 42 | component n2b = Num2Bits(4); 43 | component cst = Constants(); 44 | 45 | selector ==> n2b.in; 46 | for (i=0; i<4; i++) { 47 | n2b.out[i] ==> mux.s[i]; 48 | } 49 | for (i=0; i<16; i++) { 50 | cst.out[i] ==> mux.c[i]; 51 | } 52 | 53 | mux.out ==> out; 54 | } 55 | 56 | component main = Main(); 57 | -------------------------------------------------------------------------------- /test/circuits/pedersen2_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/pedersen.circom"; 4 | include "../../circuits/bitify.circom"; 5 | 6 | 7 | template Main() { 8 | signal input in; 9 | signal output out[2]; 10 | 11 | component pedersen = Pedersen(256); 12 | 13 | component n2b; 14 | n2b = Num2Bits(253); 15 | 16 | var i; 17 | 18 | in ==> n2b.in; 19 | 20 | for (i=0; i<253; i++) { 21 | pedersen.in[i] <== n2b.out[i]; 22 | } 23 | 24 | for (i=253; i<256; i++) { 25 | pedersen.in[i] <== 0; 26 | } 27 | 28 | pedersen.out[0] ==> out[0]; 29 | pedersen.out[1] ==> out[1]; 30 | } 31 | 32 | component main = Main(); 33 | 34 | 35 | -------------------------------------------------------------------------------- /test/circuits/pedersen_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/pedersen_old.circom"; 4 | include "../../circuits/bitify.circom"; 5 | 6 | 7 | template Main() { 8 | signal input in[2]; 9 | signal output out[2]; 10 | 11 | component pedersen = Pedersen(250*2); 12 | 13 | component n2b[2]; 14 | n2b[0] = Num2Bits(250); 15 | n2b[1] = Num2Bits(250); 16 | 17 | var i; 18 | 19 | in[0] ==> n2b[0].in; 20 | in[1] ==> n2b[1].in; 21 | 22 | for (i=0; i<250; i++) { 23 | n2b[0].out[i] ==> pedersen.in[i]; 24 | n2b[1].out[i] ==> pedersen.in[250+i]; 25 | } 26 | 27 | pedersen.out[0] ==> out[0]; 28 | pedersen.out[1] ==> out[1]; 29 | } 30 | 31 | component main = Main(); 32 | -------------------------------------------------------------------------------- /test/circuits/pointbits_loopback.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/pointbits.circom"; 4 | 5 | 6 | template Main() { 7 | signal input in[2]; 8 | 9 | var i; 10 | 11 | component p2b = Point2Bits_Strict(); 12 | component b2p = Bits2Point_Strict(); 13 | 14 | p2b.in[0] <== in[0]; 15 | p2b.in[1] <== in[1]; 16 | 17 | for (i=0; i<256; i++) { 18 | b2p.in[i] <== p2b.out[i]; 19 | } 20 | 21 | b2p.out[0] === in[0]; 22 | b2p.out[1] === in[1]; 23 | } 24 | 25 | component main = Main(); 26 | -------------------------------------------------------------------------------- /test/circuits/poseidon3_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/poseidon.circom"; 4 | 5 | component main = Poseidon(2); 6 | -------------------------------------------------------------------------------- /test/circuits/poseidon6_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/poseidon.circom"; 4 | 5 | component main = Poseidon(5); 6 | -------------------------------------------------------------------------------- /test/circuits/poseidonex_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/poseidon.circom"; 4 | 5 | component main = PoseidonEx(16, 17); -------------------------------------------------------------------------------- /test/circuits/sha256_2_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/sha256/sha256_2.circom"; 4 | 5 | template Main() { 6 | signal input a; //private 7 | signal input b; //private 8 | signal output out; 9 | 10 | component sha256_2 = Sha256_2(); 11 | 12 | sha256_2.a <== a; 13 | sha256_2.b <== b; 14 | out <== sha256_2.out; 15 | } 16 | 17 | component main = Main(); 18 | -------------------------------------------------------------------------------- /test/circuits/sha256_test448.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/sha256/sha256.circom"; 4 | 5 | component main = Sha256(448); 6 | -------------------------------------------------------------------------------- /test/circuits/sha256_test512.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/sha256/sha256.circom"; 4 | 5 | component main = Sha256(512); 6 | -------------------------------------------------------------------------------- /test/circuits/sign_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/sign.circom"; 4 | 5 | component main = Sign(); 6 | -------------------------------------------------------------------------------- /test/circuits/smtprocessor10_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/smt/smtprocessor.circom"; 4 | 5 | component main = SMTProcessor(10); 6 | -------------------------------------------------------------------------------- /test/circuits/smtverifier10_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/smt/smtverifier.circom"; 4 | 5 | component main = SMTVerifier(10); 6 | -------------------------------------------------------------------------------- /test/circuits/sum_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.0.0; 2 | 3 | include "../../circuits/bitify.circom"; 4 | include "../../circuits/binsum.circom"; 5 | 6 | template A() { 7 | signal input a; //private 8 | signal input b; 9 | signal output out; 10 | 11 | var i; 12 | 13 | component n2ba = Num2Bits(32); 14 | component n2bb = Num2Bits(32); 15 | component sum = BinSum(32,2); 16 | component b2n = Bits2Num(32); 17 | 18 | n2ba.in <== a; 19 | n2bb.in <== b; 20 | 21 | for (i=0; i<32; i++) { 22 | sum.in[0][i] <== n2ba.out[i]; 23 | sum.in[1][i] <== n2bb.out[i]; 24 | } 25 | 26 | for (i=0; i<32; i++) { 27 | b2n.in[i] <== sum.out[i]; 28 | } 29 | 30 | out <== b2n.out; 31 | } 32 | 33 | component main = A(); 34 | -------------------------------------------------------------------------------- /test/eddsa.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | 4 | const wasm_tester = require("circom_tester").wasm; 5 | 6 | const buildEddsa = require("circomlibjs").buildEddsa; 7 | const buildBabyjub = require("circomlibjs").buildBabyjub; 8 | 9 | const Scalar = require("ffjavascript").Scalar; 10 | 11 | const assert = chai.assert; 12 | 13 | function print(circuit, w, s) { 14 | console.log(s + ": " + w[circuit.getSignalIdx(s)]); 15 | } 16 | 17 | function buffer2bits(buff) { 18 | const res = []; 19 | for (let i=0; i>j)&1) { 22 | res.push(1n); 23 | } else { 24 | res.push(0n); 25 | } 26 | } 27 | } 28 | return res; 29 | } 30 | 31 | 32 | describe("EdDSA test", function () { 33 | let circuit; 34 | let eddsa; 35 | let babyJub; 36 | let F; 37 | 38 | this.timeout(100000); 39 | 40 | before( async () => { 41 | eddsa = await buildEddsa(); 42 | babyJub = await buildBabyjub(); 43 | F = babyJub.F; 44 | circuit = await wasm_tester(path.join(__dirname, "circuits", "eddsa_test.circom")); 45 | }); 46 | 47 | 48 | it("Sign a single 10 bytes from 0 to 9", async () => { 49 | const msg = Buffer.from("00010203040506070809", "hex"); 50 | 51 | // const prvKey = crypto.randomBytes(32); 52 | 53 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 54 | 55 | const pubKey = eddsa.prv2pub(prvKey); 56 | 57 | const pPubKey = babyJub.packPoint(pubKey); 58 | 59 | const signature = eddsa.signPedersen(prvKey, msg); 60 | 61 | const pSignature = eddsa.packSignature(signature); 62 | const uSignature = eddsa.unpackSignature(pSignature); 63 | 64 | assert(eddsa.verifyPedersen(msg, uSignature, pubKey)); 65 | 66 | const msgBits = buffer2bits( msg); 67 | const r8Bits = buffer2bits( pSignature.slice(0, 32)); 68 | const sBits = buffer2bits( pSignature.slice(32, 64)); 69 | const aBits = buffer2bits( pPubKey); 70 | 71 | const w = await circuit.calculateWitness({A: aBits, R8: r8Bits, S: sBits, msg: msgBits}, true); 72 | 73 | await circuit.checkConstraints(w); 74 | }); 75 | }); 76 | -------------------------------------------------------------------------------- /test/eddsamimc.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const wasm_tester = require("circom_tester").wasm; 4 | 5 | const buildEddsa = require("circomlibjs").buildEddsa; 6 | const buildBabyjub = require("circomlibjs").buildBabyjub; 7 | 8 | const assert = chai.assert; 9 | 10 | describe("EdDSA MiMC test", function () { 11 | let circuit; 12 | let eddsa; 13 | let babyJub; 14 | let F; 15 | 16 | this.timeout(100000); 17 | 18 | before( async () => { 19 | eddsa = await buildEddsa(); 20 | babyJub = await buildBabyjub(); 21 | F = babyJub.F; 22 | 23 | circuit = await wasm_tester(path.join(__dirname, "circuits", "eddsamimc_test.circom")); 24 | }); 25 | 26 | it("Sign a single number", async () => { 27 | const msg = F.e(1234); 28 | 29 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 30 | 31 | const pubKey = eddsa.prv2pub(prvKey); 32 | 33 | const signature = eddsa.signMiMC(prvKey, msg); 34 | 35 | assert(eddsa.verifyMiMC(msg, signature, pubKey)); 36 | 37 | const w = await circuit.calculateWitness({ 38 | enabled: 1, 39 | Ax: F.toObject(pubKey[0]), 40 | Ay: F.toObject(pubKey[1]), 41 | R8x: F.toObject(signature.R8[0]), 42 | R8y: F.toObject(signature.R8[1]), 43 | S: signature.S, 44 | M: F.toObject(msg)}, true); 45 | 46 | 47 | await circuit.checkConstraints(w); 48 | 49 | }); 50 | 51 | it("Detect Invalid signature", async () => { 52 | const msg = F.e(1234); 53 | 54 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 55 | 56 | const pubKey = eddsa.prv2pub(prvKey); 57 | 58 | 59 | const signature = eddsa.signMiMC(prvKey, msg); 60 | 61 | assert(eddsa.verifyMiMC(msg, signature, pubKey)); 62 | try { 63 | const w = await circuit.calculateWitness({ 64 | enabled: 1, 65 | Ax: F.toObject(pubKey[0]), 66 | Ay: F.toObject(pubKey[1]), 67 | R8x: F.toObject(F.add(signature.R8[0], F.e(1))), 68 | R8y: F.toObject(signature.R8[1]), 69 | S: signature.S, 70 | M: F.toObject(msg)}, true); 71 | assert(false); 72 | } catch(err) { 73 | assert(err.message.includes("Assert Failed")); 74 | } 75 | }); 76 | 77 | 78 | it("Test a dissabled circuit with a bad signature", async () => { 79 | const msg = F.e(1234); 80 | 81 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 82 | 83 | const pubKey = eddsa.prv2pub(prvKey); 84 | 85 | 86 | const signature = eddsa.signMiMC(prvKey, msg); 87 | 88 | assert(eddsa.verifyMiMC(msg, signature, pubKey)); 89 | 90 | const w = await circuit.calculateWitness({ 91 | enabled: 0, 92 | Ax: F.toObject(pubKey[0]), 93 | Ay: F.toObject(pubKey[1]), 94 | R8x: F.toObject(F.add(signature.R8[0], F.e(1))), 95 | R8y: F.toObject(signature.R8[1]), 96 | S: signature.S, 97 | M: F.toObject(msg)}, true); 98 | 99 | await circuit.checkConstraints(w); 100 | 101 | }); 102 | }); 103 | -------------------------------------------------------------------------------- /test/eddsaposeidon.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const wasm_tester = require("circom_tester").wasm; 4 | 5 | const buildEddsa = require("circomlibjs").buildEddsa; 6 | const buildBabyjub = require("circomlibjs").buildBabyjub; 7 | 8 | const assert = chai.assert; 9 | 10 | describe("EdDSA Poseidon test", function () { 11 | let circuit; 12 | let eddsa; 13 | let babyJub; 14 | let F; 15 | 16 | this.timeout(100000); 17 | 18 | before( async () => { 19 | eddsa = await buildEddsa(); 20 | babyJub = await buildBabyjub(); 21 | F = babyJub.F; 22 | circuit = await wasm_tester(path.join(__dirname, "circuits", "eddsaposeidon_test.circom")); 23 | }); 24 | 25 | it("Sign a single number", async () => { 26 | const msg = F.e(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 input = { 37 | enabled: 1, 38 | Ax: F.toObject(pubKey[0]), 39 | Ay: F.toObject(pubKey[1]), 40 | R8x: F.toObject(signature.R8[0]), 41 | R8y: F.toObject(signature.R8[1]), 42 | S: signature.S, 43 | M: F.toObject(msg) 44 | }; 45 | 46 | // console.log(JSON.stringify(utils.stringifyBigInts(input))); 47 | 48 | const w = await circuit.calculateWitness(input, true); 49 | 50 | await circuit.checkConstraints(w); 51 | }); 52 | 53 | it("Detect Invalid signature", async () => { 54 | const msg = F.e(1234); 55 | 56 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 57 | 58 | const pubKey = eddsa.prv2pub(prvKey); 59 | 60 | 61 | const signature = eddsa.signPoseidon(prvKey, msg); 62 | 63 | assert(eddsa.verifyPoseidon(msg, signature, pubKey)); 64 | try { 65 | await circuit.calculateWitness({ 66 | enabled: 1, 67 | Ax: F.toObject(pubKey[0]), 68 | Ay: F.toObject(pubKey[1]), 69 | R8x: F.toObject(F.add(signature.R8[0], F.e(1))), 70 | R8y: F.toObject(signature.R8[1]), 71 | S: signature.S, 72 | M: F.toObject(msg)}, true); 73 | assert(false); 74 | } catch(err) { 75 | assert(err.message.includes("Assert Failed")); 76 | } 77 | }); 78 | 79 | 80 | it("Test a dissabled circuit with a bad signature", async () => { 81 | const msg = F.e(1234); 82 | 83 | const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); 84 | 85 | const pubKey = eddsa.prv2pub(prvKey); 86 | 87 | 88 | const signature = eddsa.signPoseidon(prvKey, msg); 89 | 90 | assert(eddsa.verifyPoseidon(msg, signature, pubKey)); 91 | 92 | const w = await circuit.calculateWitness({ 93 | enabled: 0, 94 | Ax: F.toObject(pubKey[0]), 95 | Ay: F.toObject(pubKey[1]), 96 | R8x: F.toObject(F.add(signature.R8[0], F.e(1))), 97 | R8y: F.toObject(signature.R8[1]), 98 | S: signature.S, 99 | M: F.toObject(msg)}, true); 100 | 101 | await circuit.checkConstraints(w); 102 | }); 103 | }); 104 | -------------------------------------------------------------------------------- /test/escalarmul.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const wasm_tester = require("circom_tester").wasm; 4 | const buildBabyjub = require("circomlibjs").buildBabyjub; 5 | 6 | const Scalar = require("ffjavascript").Scalar; 7 | 8 | const assert = chai.assert; 9 | 10 | function print(circuit, w, s) { 11 | console.log(s + ": " + w[circuit.getSignalIdx(s)]); 12 | } 13 | 14 | describe("Exponentioation test", function () { 15 | let babyJub; 16 | let Fr; 17 | this.timeout(100000); 18 | 19 | before( async () => { 20 | babyJub = await buildBabyjub(); 21 | Fr = babyJub.F; 22 | }); 23 | 24 | it("Should generate the Exponentiation table in k=0", async () => { 25 | 26 | const circuit = await wasm_tester(path.join(__dirname, "circuits", "escalarmulw4table_test.circom")); 27 | 28 | const w = await circuit.calculateWitness({in: 1}); 29 | 30 | await circuit.checkConstraints(w); 31 | 32 | let g = [ 33 | Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), 34 | Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") 35 | ]; 36 | 37 | let dbl= [Fr.e("0"), Fr.e("1")]; 38 | 39 | const expectedOut = []; 40 | 41 | for (let i=0; i<16; i++) { 42 | 43 | expectedOut.push([Fr.toObject(dbl[0]), Fr.toObject(dbl[1])]); 44 | dbl = babyJub.addPoint(dbl,g); 45 | } 46 | 47 | await circuit.assertOut(w, {out: expectedOut}); 48 | 49 | }); 50 | 51 | it("Should generate the Exponentiation table in k=3", async () => { 52 | 53 | const circuit = await wasm_tester(path.join(__dirname, "circuits", "escalarmulw4table_test3.circom")); 54 | 55 | const w = await circuit.calculateWitness({in: 1}); 56 | 57 | await circuit.checkConstraints(w); 58 | 59 | let g = [ 60 | Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), 61 | Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") 62 | ]; 63 | 64 | for (let i=0; i<12;i++) { 65 | g = babyJub.addPoint(g,g); 66 | } 67 | 68 | let dbl= [Fr.e("0"), Fr.e("1")]; 69 | 70 | const expectedOut = []; 71 | 72 | for (let i=0; i<16; i++) { 73 | expectedOut.push([Fr.toObject(dbl[0]), Fr.toObject(dbl[1])]); 74 | 75 | dbl = babyJub.addPoint(dbl,g); 76 | } 77 | 78 | await circuit.assertOut(w, {out: expectedOut}); 79 | 80 | }); 81 | 82 | it("Should exponentiate g^31", async () => { 83 | 84 | const circuit = await wasm_tester(path.join(__dirname, "circuits", "escalarmul_test.circom")); 85 | 86 | const w = await circuit.calculateWitness({"in": 31}); 87 | 88 | await circuit.checkConstraints(w); 89 | 90 | let g = [ 91 | Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), 92 | Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") 93 | ]; 94 | 95 | let c = [Fr.e(0), Fr.e(1)]; 96 | 97 | for (let i=0; i<31;i++) { 98 | c = babyJub.addPoint(c,g); 99 | } 100 | 101 | await circuit.assertOut(w, {out: [Fr.toObject(c[0]), Fr.toObject(c[1])] }); 102 | 103 | const w2 = await circuit.calculateWitness({"in": Scalar.add(Scalar.shl(Scalar.e(1), 252),Scalar.e(1))}); 104 | 105 | c = [g[0], g[1]]; 106 | for (let i=0; i<252;i++) { 107 | c = babyJub.addPoint(c,c); 108 | } 109 | c = babyJub.addPoint(c,g); 110 | 111 | await circuit.assertOut(w2, {out: [Fr.toObject(c[0]), Fr.toObject(c[1])] }); 112 | 113 | }).timeout(10000000); 114 | 115 | it("Number of constrains for 256 bits", async () => { 116 | 117 | const circuit = await wasm_tester(path.join(__dirname, "circuits", "escalarmul_test_min.circom")); 118 | 119 | }).timeout(10000000); 120 | 121 | }); 122 | -------------------------------------------------------------------------------- /test/escalarmulany.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const wasm_tester = require("circom_tester").wasm; 4 | 5 | const F1Field = require("ffjavascript").F1Field; 6 | const Scalar = require("ffjavascript").Scalar; 7 | exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); 8 | const Fr = new F1Field(exports.p); 9 | 10 | function print(circuit, w, s) { 11 | console.log(s + ": " + w[circuit.getSignalIdx(s)]); 12 | } 13 | 14 | describe("Escalarmul test", function () { 15 | let circuitEMulAny; 16 | 17 | this.timeout(100000); 18 | 19 | let g; 20 | 21 | before( async() => { 22 | circuitEMulAny = await wasm_tester(path.join(__dirname, "circuits", "escalarmulany_test.circom")); 23 | g = [ 24 | Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), 25 | Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") 26 | ] 27 | }); 28 | 29 | it("Should generate Same escalar mul", async () => { 30 | 31 | const w = await circuitEMulAny.calculateWitness({"e": 1, "p": g}); 32 | 33 | await circuitEMulAny.checkConstraints(w); 34 | 35 | await circuitEMulAny.assertOut(w, {out: g}, true); 36 | 37 | }); 38 | 39 | it("If multiply by order should return 0", async () => { 40 | 41 | const r = Fr.e("2736030358979909402780800718157159386076813972158567259200215660948447373041"); 42 | const w = await circuitEMulAny.calculateWitness({"e": r, "p": g}); 43 | 44 | await circuitEMulAny.checkConstraints(w); 45 | 46 | await circuitEMulAny.assertOut(w, {out: [0,1]}, true); 47 | 48 | }); 49 | 50 | }); 51 | 52 | -------------------------------------------------------------------------------- /test/escalarmulfix.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const wasm_tester = require("circom_tester").wasm; 4 | const buildBabyjub = require("circomlibjs").buildBabyjub; 5 | const Scalar = require("ffjavascript").Scalar; 6 | 7 | const assert = chai.assert; 8 | 9 | function print(circuit, w, s) { 10 | console.log(s + ": " + w[circuit.getSignalIdx(s)]); 11 | } 12 | 13 | describe("Escalarmul test", function () { 14 | let babyJub; 15 | let Fr; 16 | let circuit; 17 | 18 | this.timeout(100000); 19 | 20 | 21 | before( async() => { 22 | babyJub = await buildBabyjub(); 23 | Fr = babyJub.F; 24 | circuit = await wasm_tester(path.join(__dirname, "circuits", "escalarmulfix_test.circom")); 25 | }); 26 | 27 | it("Should generate Same escalar mul", async () => { 28 | 29 | const w = await circuit.calculateWitness({"e": 0}); 30 | 31 | await circuit.checkConstraints(w); 32 | 33 | await circuit.assertOut(w, {out: [0,1]}, true); 34 | 35 | }); 36 | 37 | it("Should generate Same escalar mul", async () => { 38 | 39 | const w = await circuit.calculateWitness({"e": 1}, true); 40 | 41 | await circuit.checkConstraints(w); 42 | 43 | await circuit.assertOut(w, {out: [Fr.toObject(babyJub.Base8[0]), Fr.toObject(babyJub.Base8[1])]}); 44 | 45 | }); 46 | 47 | it("Should generate scalar mul of a specific constant", async () => { 48 | 49 | const s = Scalar.e("2351960337287830298912035165133676222414898052661454064215017316447594616519"); 50 | const base8 = [ 51 | Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), 52 | Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") 53 | ]; 54 | 55 | const w = await circuit.calculateWitness({"e": s}, true); 56 | 57 | await circuit.checkConstraints(w); 58 | 59 | const expectedRes = babyJub.mulPointEscalar(base8, s); 60 | 61 | await circuit.assertOut(w, {out: [Fr.toObject(expectedRes[0]), Fr.toObject(expectedRes[1])]}); 62 | 63 | }); 64 | 65 | it("Should generate scalar mul of the firsts 50 elements", async () => { 66 | 67 | const base8 = [ 68 | Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), 69 | Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") 70 | ]; 71 | 72 | for (let i=0; i<50; i++) { 73 | const s = Scalar.e(i); 74 | 75 | const w = await circuit.calculateWitness({"e": s}, true); 76 | 77 | await circuit.checkConstraints(w); 78 | 79 | const expectedRes = babyJub.mulPointEscalar(base8, s); 80 | 81 | await circuit.assertOut(w, {out: [Fr.toObject(expectedRes[0]), Fr.toObject(expectedRes[1])]}); 82 | } 83 | }); 84 | 85 | it("If multiply by order should return 0", async () => { 86 | 87 | const w = await circuit.calculateWitness({"e": babyJub.subOrder }, true); 88 | 89 | await circuit.checkConstraints(w); 90 | 91 | await circuit.assertOut(w, {out: [0,1]}); 92 | }); 93 | 94 | }); 95 | 96 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /test/mimccircuit.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const wasm_tester = require("circom_tester").wasm; 4 | 5 | const buildMimc7 = require("circomlibjs").buildMimc7; 6 | 7 | describe("MiMC Circuit test", function () { 8 | let circuit; 9 | let mimc7; 10 | 11 | this.timeout(100000); 12 | 13 | before( async () => { 14 | mimc7 = await buildMimc7(); 15 | circuit = await wasm_tester(path.join(__dirname, "circuits", "mimc_test.circom")); 16 | }); 17 | 18 | it("Should check constrain", async () => { 19 | const w = await circuit.calculateWitness({x_in: 1, k: 2}, true); 20 | 21 | const res2 = mimc7.hash(1,2,91); 22 | 23 | await circuit.assertOut(w, {out: mimc7.F.toObject(res2)}); 24 | 25 | await circuit.checkConstraints(w); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/mimcspongecircuit.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const wasm_tester = require("circom_tester").wasm; 3 | 4 | const buildMimcSponge = require("circomlibjs").buildMimcSponge; 5 | 6 | 7 | describe("MiMC Sponge Circuit test", function () { 8 | let circuit; 9 | let mimcSponge; 10 | let F; 11 | 12 | this.timeout(100000); 13 | 14 | before( async () => { 15 | mimcSponge = await buildMimcSponge(); 16 | F = mimcSponge.F; 17 | }); 18 | 19 | 20 | it("Should check permutation", async () => { 21 | 22 | circuit = await wasm_tester(path.join(__dirname, "circuits", "mimc_sponge_test.circom")); 23 | 24 | const w = await circuit.calculateWitness({xL_in: 1, xR_in: 2, k: 3}); 25 | 26 | const out2 = mimcSponge.hash(1,2,3); 27 | 28 | await circuit.assertOut(w, {xL_out: F.toObject(out2.xL), xR_out: F.toObject(out2.xR)}); 29 | 30 | await circuit.checkConstraints(w); 31 | 32 | }); 33 | 34 | it("Should check hash", async () => { 35 | circuit = await wasm_tester(path.join(__dirname, "circuits", "mimc_sponge_hash_test.circom")); 36 | 37 | const w = await circuit.calculateWitness({ins: [1, 2], k: 0}); 38 | 39 | const out2 = mimcSponge.multiHash([1,2], 0, 3); 40 | 41 | for (let i=0; i { 25 | babyJub = await buildBabyjub(); 26 | Fr = babyJub.F; 27 | g = [ 28 | Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"), 29 | Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203") 30 | ]; 31 | 32 | circuitE2M = await wasm_tester(path.join(__dirname, "circuits", "edwards2montgomery.circom")); 33 | await circuitE2M.loadSymbols(); 34 | circuitM2E = await wasm_tester(path.join(__dirname, "circuits", "montgomery2edwards.circom")); 35 | await circuitM2E.loadSymbols(); 36 | circuitMAdd = await wasm_tester(path.join(__dirname, "circuits", "montgomeryadd.circom")); 37 | await circuitMAdd.loadSymbols(); 38 | circuitMDouble = await wasm_tester(path.join(__dirname, "circuits", "montgomerydouble.circom")); 39 | await circuitMDouble.loadSymbols(); 40 | }); 41 | 42 | it("Convert Edwards to Montgomery and back again", async () => { 43 | let w, xout, yout; 44 | 45 | w = await circuitE2M.calculateWitness({ in: [Fr.toObject(g[0]), Fr.toObject(g[1])]}, true); 46 | 47 | xout = w[circuitE2M.symbols["main.out[0]"].varIdx]; 48 | yout = w[circuitE2M.symbols["main.out[1]"].varIdx]; 49 | 50 | mg = [xout, yout]; 51 | 52 | w = await circuitM2E.calculateWitness({ in: [xout, yout]}, true); 53 | 54 | xout = w[circuitM2E.symbols["main.out[0]"].varIdx]; 55 | yout = w[circuitM2E.symbols["main.out[1]"].varIdx]; 56 | 57 | assert(Fr.eq(Fr.e(xout), g[0])); 58 | assert(Fr.eq(Fr.e(yout), g[1])); 59 | }); 60 | it("Should double a point", async () => { 61 | let w, xout, yout; 62 | 63 | g2 = babyJub.addPoint(g,g); 64 | 65 | w = await circuitMDouble.calculateWitness({ in: mg}, true); 66 | 67 | xout = w[circuitE2M.symbols["main.out[0]"].varIdx]; 68 | yout = w[circuitE2M.symbols["main.out[1]"].varIdx]; 69 | 70 | mg2 = [xout, yout]; 71 | 72 | w = await circuitM2E.calculateWitness({ in: mg2}, true); 73 | 74 | xout = w[circuitM2E.symbols["main.out[0]"].varIdx]; 75 | yout = w[circuitM2E.symbols["main.out[1]"].varIdx]; 76 | 77 | 78 | assert(Fr.eq(Fr.e(xout), g2[0])); 79 | assert(Fr.eq(Fr.e(yout), g2[1])); 80 | }); 81 | it("Should add a point", async () => { 82 | let w, xout, yout; 83 | 84 | g3 = babyJub.addPoint(g,g2); 85 | 86 | w = await circuitMAdd.calculateWitness({ in1: mg, in2: mg2}, true); 87 | 88 | xout = w[circuitMAdd.symbols["main.out[0]"].varIdx]; 89 | yout = w[circuitMAdd.symbols["main.out[1]"].varIdx]; 90 | 91 | mg3 = [xout, yout]; 92 | 93 | w = await circuitM2E.calculateWitness({ in: mg3}, true); 94 | 95 | xout = w[circuitM2E.symbols["main.out[0]"].varIdx]; 96 | yout = w[circuitM2E.symbols["main.out[1]"].varIdx]; 97 | 98 | assert(Fr.eq(Fr.e(xout), g3[0])); 99 | assert(Fr.eq(Fr.e(yout), g3[1])); 100 | }); 101 | }); 102 | -------------------------------------------------------------------------------- /test/multiplexer.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const wasm_tester = require("circom_tester").wasm; 3 | const F1Field = require("ffjavascript").F1Field; 4 | const Scalar = require("ffjavascript").Scalar; 5 | exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); 6 | const Fr = new F1Field(exports.p); 7 | 8 | describe("Mux4 test", function() { 9 | this.timeout(100000); 10 | it("Should create a constant multiplexer 4", async () => { 11 | 12 | const circuit = await wasm_tester(path.join(__dirname, "circuits", "mux4_1.circom")); 13 | 14 | const ct16 = [ 15 | Fr.e("123"), 16 | Fr.e("456"), 17 | Fr.e("789"), 18 | Fr.e("012"), 19 | Fr.e("111"), 20 | Fr.e("222"), 21 | Fr.e("333"), 22 | Fr.e("4546"), 23 | Fr.e("134523"), 24 | Fr.e("44356"), 25 | Fr.e("15623"), 26 | Fr.e("4566"), 27 | Fr.e("1223"), 28 | Fr.e("4546"), 29 | Fr.e("4256"), 30 | Fr.e("4456") 31 | ]; 32 | 33 | for (let i=0; i<16; i++) { 34 | const w = await circuit.calculateWitness({ "selector": i }, true); 35 | 36 | await circuit.checkConstraints(w); 37 | 38 | await circuit.assertOut(w, {out: ct16[i]}); 39 | } 40 | }); 41 | 42 | it("Should create a constant multiplexer 3", async () => { 43 | 44 | const circuit = await wasm_tester(path.join(__dirname, "circuits", "mux3_1.circom")); 45 | 46 | const ct8 = [ 47 | Fr.e("37"), 48 | Fr.e("47"), 49 | Fr.e("53"), 50 | Fr.e("71"), 51 | Fr.e("89"), 52 | Fr.e("107"), 53 | Fr.e("163"), 54 | Fr.e("191") 55 | ]; 56 | 57 | for (let i=0; i<8; i++) { 58 | const w = await circuit.calculateWitness({ "selector": i }, true); 59 | 60 | await circuit.checkConstraints(w); 61 | 62 | await circuit.assertOut(w, {out: ct8[i]}); 63 | } 64 | }); 65 | it("Should create a constant multiplexer 2", async () => { 66 | 67 | const circuit = await wasm_tester(path.join(__dirname, "circuits", "mux2_1.circom")); 68 | 69 | const ct4 = [ 70 | Fr.e("37"), 71 | Fr.e("47"), 72 | Fr.e("53"), 73 | Fr.e("71"), 74 | ]; 75 | 76 | for (let i=0; i<4; i++) { 77 | const w = await circuit.calculateWitness({ "selector": i }, true); 78 | 79 | await circuit.checkConstraints(w); 80 | 81 | await circuit.assertOut(w, {out: ct4[i]}); 82 | } 83 | }); 84 | it("Should create a constant multiplexer 1", async () => { 85 | 86 | const circuit = await wasm_tester(path.join(__dirname, "circuits", "mux1_1.circom")); 87 | 88 | const ct2 = [ 89 | Fr.e("37"), 90 | Fr.e("47"), 91 | ]; 92 | 93 | for (let i=0; i<2; i++) { 94 | const w = await circuit.calculateWitness({ "selector": i }, true); 95 | 96 | await circuit.checkConstraints(w); 97 | 98 | await circuit.assertOut(w, {out: ct2[i]}); 99 | } 100 | }); 101 | }); 102 | -------------------------------------------------------------------------------- /test/pedersen.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | 4 | const Scalar = require("ffjavascript").Scalar; 5 | 6 | const wasm_tester = require("circom_tester").wasm; 7 | 8 | const buildBabyjub = require("circomlibjs").buildBabyjub; 9 | 10 | 11 | describe("Double Pedersen test", function() { 12 | let babyJub; 13 | let Fr; 14 | let PBASE; 15 | let circuit; 16 | this.timeout(100000); 17 | before( async() => { 18 | babyJub = await buildBabyjub(); 19 | Fr = babyJub.F; 20 | PBASE = 21 | [ 22 | [Fr.e("10457101036533406547632367118273992217979173478358440826365724437999023779287"),Fr.e("19824078218392094440610104313265183977899662750282163392862422243483260492317")], 23 | [Fr.e("2671756056509184035029146175565761955751135805354291559563293617232983272177"),Fr.e("2663205510731142763556352975002641716101654201788071096152948830924149045094")], 24 | [Fr.e("5802099305472655231388284418920769829666717045250560929368476121199858275951"),Fr.e("5980429700218124965372158798884772646841287887664001482443826541541529227896")], 25 | [Fr.e("7107336197374528537877327281242680114152313102022415488494307685842428166594"),Fr.e("2857869773864086953506483169737724679646433914307247183624878062391496185654")], 26 | [Fr.e("20265828622013100949498132415626198973119240347465898028410217039057588424236"),Fr.e("1160461593266035632937973507065134938065359936056410650153315956301179689506")] 27 | ]; 28 | circuit = await wasm_tester(path.join(__dirname, "circuits", "pedersen_test.circom")); 29 | 30 | }); 31 | 32 | it("Should pedersen at zero", async () => { 33 | 34 | let w; 35 | 36 | w = await circuit.calculateWitness({ in: ["0", "0"]}, true); 37 | 38 | await circuit.assertOut(w, {out: [0,1]}); 39 | 40 | }); 41 | it("Should pedersen at one first generator", async () => { 42 | let w; 43 | 44 | w = await circuit.calculateWitness({ in: ["1", "0"]}, true); 45 | 46 | await circuit.assertOut(w, {out: [Fr.toObject(PBASE[0][0]), Fr.toObject(PBASE[0][1])]}); 47 | 48 | }); 49 | it("Should pedersen at one second generator", async () => { 50 | let w; 51 | 52 | w = await circuit.calculateWitness({ in: ["0", "1"]}, true); 53 | 54 | await circuit.assertOut(w, {out: [Fr.toObject(PBASE[1][0]), Fr.toObject(PBASE[1][1])]}); 55 | 56 | }); 57 | it("Should pedersen at mixed generators", async () => { 58 | let w; 59 | w = await circuit.calculateWitness({ in: ["3", "7"]}, true); 60 | 61 | const r = babyJub.addPoint( 62 | babyJub.mulPointEscalar(PBASE[0], 3), 63 | babyJub.mulPointEscalar(PBASE[1], 7) 64 | ); 65 | 66 | await circuit.assertOut(w, {out: [Fr.toObject(r[0]), Fr.toObject(r[1])]}); 67 | 68 | }); 69 | it("Should pedersen all ones", async () => { 70 | let w; 71 | 72 | const allOnes = Scalar.sub(Scalar.shl(Scalar.e(1), 250), Scalar.e(1)); 73 | w = await circuit.calculateWitness({ in: [allOnes, allOnes]}, true); 74 | 75 | 76 | const r2 = babyJub.addPoint( 77 | babyJub.mulPointEscalar(PBASE[0], allOnes), 78 | babyJub.mulPointEscalar(PBASE[1], allOnes) 79 | ); 80 | 81 | await circuit.assertOut(w, {out: [Fr.toObject(r2[0]), Fr.toObject(r2[1])]}); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /test/pedersen2.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | const Scalar = require("ffjavascript").Scalar; 4 | 5 | const buildPedersenHash = require("circomlibjs").buildPedersenHash; 6 | const buildBabyJub = require("circomlibjs").buildBabyjub; 7 | 8 | const wasm_tester = require("circom_tester").wasm; 9 | 10 | 11 | describe("Pedersen test", function() { 12 | let babyJub 13 | let pedersen; 14 | let F; 15 | let circuit; 16 | this.timeout(100000); 17 | before( async() => { 18 | 19 | babyJub = await buildBabyJub(); 20 | F = babyJub.F; 21 | pedersen = await buildPedersenHash(); 22 | circuit = await wasm_tester(path.join(__dirname, "circuits", "pedersen2_test.circom")); 23 | }); 24 | it("Should pedersen at zero", async () => { 25 | 26 | let w; 27 | 28 | w = await circuit.calculateWitness({ in: 0}, true); 29 | 30 | const b = Buffer.alloc(32); 31 | 32 | const h = pedersen.hash(b); 33 | const hP = babyJub.unpackPoint(h); 34 | 35 | await circuit.assertOut(w, {out: [F.toObject(hP[0]), F.toObject(hP[1])] }); 36 | 37 | }); 38 | it("Should pedersen with 253 ones", async () => { 39 | 40 | let w; 41 | 42 | const n = F.e(Scalar.sub(Scalar.shl(Scalar.e(1), 253), Scalar.e(1))); 43 | 44 | w = await circuit.calculateWitness({ in: F.toObject(n)}, true); 45 | 46 | const b = Buffer.alloc(32); 47 | for (let i=0; i<31; i++) b[i] = 0xFF; 48 | b[31] = 0x1F; 49 | 50 | const h = pedersen.hash(b); 51 | const hP = babyJub.unpackPoint(h); 52 | 53 | await circuit.assertOut(w, {out: [F.toObject(hP[0]), F.toObject(hP[1])] }); 54 | 55 | }); 56 | }); 57 | -------------------------------------------------------------------------------- /test/point2bits.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const wasm_tester = require("circom_tester").wasm; 3 | const buildBabyJub = require("circomlibjs").buildBabyjub; 4 | 5 | const babyJub = require("circomlibjs").babyjub; 6 | 7 | 8 | describe("Point 2 bits test", function() { 9 | let babyJub; 10 | let F; 11 | let circuit; 12 | this.timeout(100000); 13 | before( async() => { 14 | babyJub = await buildBabyJub(); 15 | F = babyJub.F; 16 | 17 | circuit = await wasm_tester(path.join(__dirname, "circuits", "pointbits_loopback.circom")); 18 | }); 19 | 20 | it("Should do the both convertions for 8Base", async () => { 21 | const w = await circuit.calculateWitness({ in: [F.toObject(babyJub.Base8[0]), F.toObject(babyJub.Base8[1])]}, true); 22 | 23 | await circuit.checkConstraints(w); 24 | }); 25 | it("Should do the both convertions for Zero point", async () => { 26 | const w = await circuit.calculateWitness({ in: [0, 1]}, true); 27 | 28 | await circuit.checkConstraints(w); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /test/poseidoncircuit.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const wasm_tester = require("circom_tester").wasm; 4 | 5 | const buildPoseidon = require("circomlibjs").buildPoseidon; 6 | 7 | const assert = chai.assert; 8 | 9 | describe("Poseidon Circuit test", function () { 10 | let poseidon; 11 | let F; 12 | let circuit6; 13 | let circuit3; 14 | let circuitEx; 15 | 16 | this.timeout(1000000); 17 | 18 | before( async () => { 19 | poseidon = await buildPoseidon(); 20 | F = poseidon.F; 21 | circuit6 = await wasm_tester(path.join(__dirname, "circuits", "poseidon6_test.circom")); 22 | circuit3 = await wasm_tester(path.join(__dirname, "circuits", "poseidon3_test.circom")); 23 | circuitEx = await wasm_tester(path.join(__dirname, "circuits", "poseidonex_test.circom")); 24 | }); 25 | 26 | it("Should check constrain of hash([1, 2]) t=6", async () => { 27 | const w = await circuit6.calculateWitness({inputs: [1, 2, 0,0,0]}, true); 28 | 29 | const res2 = poseidon([1,2,0,0,0]); 30 | 31 | assert(F.eq(F.e("1018317224307729531995786483840663576608797660851238720571059489595066344487"), F.e(res2))); 32 | await circuit6.assertOut(w, {out : F.toObject(res2)}); 33 | await circuit6.checkConstraints(w); 34 | }); 35 | 36 | it("Should check constrain of hash([3, 4]) t=6", async () => { 37 | const w = await circuit6.calculateWitness({inputs: [3, 4,5,10,23]}); 38 | 39 | const res2 = poseidon([3, 4,5,10,23]); 40 | 41 | assert(F.eq(F.e("13034429309846638789535561449942021891039729847501137143363028890275222221409"), F.e(res2))); 42 | await circuit6.assertOut(w, {out : F.toObject(res2)}); 43 | await circuit6.checkConstraints(w); 44 | }); 45 | 46 | 47 | it("Should check constrain of hash([1, 2]) t=3", async () => { 48 | const w = await circuit3.calculateWitness({inputs: [1, 2]}); 49 | 50 | const res2 = poseidon([1,2]); 51 | 52 | assert(F.eq(F.e("7853200120776062878684798364095072458815029376092732009249414926327459813530"), F.e(res2))); 53 | await circuit3.assertOut(w, {out : F.toObject(res2)}); 54 | await circuit3.checkConstraints(w); 55 | }); 56 | 57 | it("Should check constrain of hash([3, 4]) t=3", async () => { 58 | const w = await circuit3.calculateWitness({inputs: [3, 4]}); 59 | 60 | const res2 = poseidon([3, 4]); 61 | 62 | assert(F.eq(F.e("14763215145315200506921711489642608356394854266165572616578112107564877678998"), F.e(res2))); 63 | await circuit3.assertOut(w, {out : F.toObject(res2)}); 64 | await circuit3.checkConstraints(w); 65 | }); 66 | 67 | it("Should check constrain of hash with state and 16 ins and outs", async () => { 68 | const ins = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] 69 | const w = await circuitEx.calculateWitness({inputs: ins, initialState: 17}); 70 | 71 | const res2 = poseidon(ins, 17, 17); 72 | const res2f = []; 73 | for (let i=0; i> (7-j) &1)); 23 | } 24 | } 25 | return res; 26 | } 27 | 28 | function bitArray2buffer(a) { 29 | const len = Math.floor((a.length -1 )/8)+1; 30 | const b = new Buffer.alloc(len); 31 | 32 | for (let i=0; i { 45 | const b = new Buffer.alloc(64); 46 | for (let i=0; i<64; i++) { 47 | b[i] = i+1; 48 | } 49 | const a = buffer2bitArray(b); 50 | const b2 = bitArray2buffer(a); 51 | 52 | assert.equal(b.toString("hex"), b2.toString("hex"), true); 53 | }); 54 | 55 | it("Should calculate a hash of 1 compressor", async () => { 56 | const cir = await wasm_tester(path.join(__dirname, "circuits", "sha256_2_test.circom")); 57 | 58 | const witness = await cir.calculateWitness({ "a": "1", "b": "2" }, true); 59 | 60 | const b = new Buffer.alloc(54); 61 | b[26] = 1; 62 | b[53] = 2; 63 | 64 | const hash = crypto.createHash("sha256") 65 | .update(b) 66 | .digest("hex"); 67 | const r = "0x" + hash.slice(10); 68 | 69 | const hash2 = sha256.hash(b.toString("hex"), {msgFormat: "hex-bytes"}); 70 | 71 | assert.equal(hash, hash2); 72 | 73 | assert(Fr.eq(witness[1], Fr.e(r))); 74 | }).timeout(1000000); 75 | 76 | it("Should calculate a hash of 2 compressor", async () => { 77 | const cir = await wasm_tester(path.join(__dirname, "circuits", "sha256_test512.circom")); 78 | 79 | const b = new Buffer.alloc(64); 80 | for (let i=0; i<64; i++) { 81 | b[i] = i+1; 82 | } 83 | 84 | const hash = crypto.createHash("sha256") 85 | .update(b) 86 | .digest("hex"); 87 | 88 | const arrIn = buffer2bitArray(b); 89 | const witness = await cir.calculateWitness({ "in": arrIn }, true); 90 | 91 | const arrOut = witness.slice(1, 257); 92 | const hash2 = bitArray2buffer(arrOut).toString("hex"); 93 | 94 | assert.equal(hash, hash2); 95 | 96 | }).timeout(1000000); 97 | it ("Should calculate a hash of 2 compressor", async () => { 98 | const cir = await wasm_tester(path.join(__dirname, "circuits", "sha256_test448.circom")); 99 | 100 | const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; 101 | 102 | const b = Buffer.from(testStr, "utf8"); 103 | 104 | const hash = crypto.createHash("sha256") 105 | .update(b) 106 | .digest("hex"); 107 | 108 | const arrIn = buffer2bitArray(b); 109 | 110 | const witness = await cir.calculateWitness({ "in": arrIn }, true); 111 | 112 | const arrOut = witness.slice(1, 257); 113 | const hash2 = bitArray2buffer(arrOut).toString("hex"); 114 | 115 | assert.equal(hash, hash2); 116 | }); 117 | 118 | }); 119 | -------------------------------------------------------------------------------- /test/sign.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const F1Field = require("ffjavascript").F1Field; 3 | const Scalar = require("ffjavascript").Scalar; 4 | exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); 5 | const Fr = new F1Field(exports.p); 6 | const wasm_tester = require("circom_tester").wasm; 7 | 8 | function print(circuit, w, s) { 9 | console.log(s + ": " + w[circuit.getSignalIdx(s)]); 10 | } 11 | 12 | function getBits(v, n) { 13 | const res = []; 14 | for (let i=0; i { 31 | circuit = await wasm_tester(path.join(__dirname, "circuits", "sign_test.circom")); 32 | }); 33 | 34 | it("Sign of 0", async () => { 35 | const inp = getBits(Scalar.e(0), 254); 36 | const w = await circuit.calculateWitness({in: inp}, true); 37 | 38 | await circuit.assertOut(w, {sign: 0}); 39 | }); 40 | 41 | it("Sign of 3", async () => { 42 | const inp = getBits(Scalar.e(3), 254); 43 | const w = await circuit.calculateWitness({in: inp}, true); 44 | 45 | await circuit.assertOut(w, {sign: 0}); 46 | }); 47 | 48 | it("Sign of q/2", async () => { 49 | const inp = getBits(Scalar.shr(q, 1), 254); 50 | const w = await circuit.calculateWitness({in: inp}, true); 51 | 52 | await circuit.assertOut(w, {sign: 0}); 53 | }); 54 | 55 | it("Sign of q/2+1", async () => { 56 | const inp = getBits(Scalar.add(Scalar.shr(q, 1), 1) , 254); 57 | const w = await circuit.calculateWitness({in: inp}, true); 58 | 59 | await circuit.assertOut(w, {sign: 1}); 60 | }); 61 | 62 | it("Sign of q-1", async () => { 63 | const inp = getBits(Scalar.sub(q, 1), 254); 64 | const w = await circuit.calculateWitness({in: inp}, true); 65 | 66 | await circuit.assertOut(w, {sign: 1}); 67 | }); 68 | 69 | it("Sign of q", async () => { 70 | const inp = getBits(q, 254); 71 | const w = await circuit.calculateWitness({in: inp}, true); 72 | 73 | await circuit.assertOut(w, {sign: 1}); 74 | }); 75 | 76 | it("Sign of all ones", async () => { 77 | const inp = getBits(Scalar.sub(Scalar.shl(1,254),1), 254); 78 | const w = await circuit.calculateWitness({in: inp}, true); 79 | 80 | await circuit.assertOut(w, {sign: 1}); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /test/smtverifier.js: -------------------------------------------------------------------------------- 1 | const chai = require("chai"); 2 | const path = require("path"); 3 | const Scalar = require("ffjavascript").Scalar; 4 | const wasm_tester = require("circom_tester").wasm; 5 | 6 | const newMemEmptyTrie = require("circomlibjs").newMemEmptyTrie; 7 | 8 | const assert = chai.assert; 9 | 10 | function print(circuit, w, s) { 11 | console.log(s + ": " + w[circuit.getSignalIdx(s)]); 12 | } 13 | 14 | async function testInclusion(tree, _key, circuit) { 15 | const key = tree.F.e(_key); 16 | const res = await tree.find(key); 17 | 18 | assert(res.found); 19 | let siblings = res.siblings; 20 | for (let i=0; i { 72 | circuit = await wasm_tester(path.join(__dirname, "circuits", "smtverifier10_test.circom")); 73 | 74 | tree = await newMemEmptyTrie(); 75 | Fr = tree.F; 76 | await tree.insert(7,77); 77 | await tree.insert(8,88); 78 | await tree.insert(32,3232); 79 | }); 80 | 81 | it("Check inclussion in a tree of 3", async () => { 82 | await testInclusion(tree, 7, circuit); 83 | await testInclusion(tree, 8, circuit); 84 | await testInclusion(tree, 32, circuit); 85 | }); 86 | 87 | it("Check exclussion in a tree of 3", async () => { 88 | await testExclusion(tree, 0, circuit); 89 | await testExclusion(tree, 6, circuit); 90 | await testExclusion(tree, 9, circuit); 91 | await testExclusion(tree, 33, circuit); 92 | await testExclusion(tree, 31, circuit); 93 | await testExclusion(tree, 16, circuit); 94 | await testExclusion(tree, 64, circuit); 95 | }); 96 | 97 | it("Check not enabled accepts any thing", async () => { 98 | let siblings = []; 99 | for (let i=0; i<10; i++) siblings.push(i); 100 | 101 | const w = await circuit.calculateWitness({ 102 | enabled: 0, 103 | fnc: 0, 104 | root: 1, 105 | siblings: siblings, 106 | oldKey: 22, 107 | oldValue: 33, 108 | isOld0: 0, 109 | key: 44, 110 | value: 0 111 | }); 112 | 113 | 114 | await circuit.checkConstraints(w); 115 | }); 116 | 117 | it("Check inclussion Adria case", async () => { 118 | const e1_hi= Fr.e("17124152697573569611556136390143205198134245887034837071647643529178599000839"); 119 | const e1_hv= Fr.e("19650379996168153643111744440707177573540245771926102415571667548153444658179"); 120 | 121 | const e2ok_hi= Fr.e("16498254692537945203721083102154618658340563351558973077349594629411025251262"); 122 | const e2ok_hv= Fr.e("19650379996168153643111744440707177573540245771926102415571667548153444658179"); 123 | 124 | const e2fail_hi= Fr.e("17195092312975762537892237130737365903429674363577646686847513978084990105579"); 125 | const e2fail_hv= Fr.e("19650379996168153643111744440707177573540245771926102415571667548153444658179"); 126 | 127 | const tree1 = await newMemEmptyTrie(); 128 | await tree1.insert(e1_hi,e1_hv); 129 | await tree1.insert(e2ok_hi,e2ok_hv); 130 | 131 | await testInclusion(tree1, e2ok_hi, circuit); 132 | 133 | const tree2 = await newMemEmptyTrie(); 134 | await tree2.insert(e1_hi,e1_hv); 135 | await tree2.insert(e2fail_hi,e2fail_hv); 136 | 137 | await testInclusion(tree2, e2fail_hi, circuit); 138 | }); 139 | 140 | 141 | }); 142 | --------------------------------------------------------------------------------