├── .codecov.yml ├── .github └── workflows │ ├── build.yml │ └── coverage.yml ├── .gitignore ├── .gitmodules ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── LICENSE-MIT ├── README.md ├── arkworks-benchmarks ├── .gitignore ├── Cargo.toml └── src │ └── main.rs ├── arkworks-native-gadgets ├── .gitignore ├── Cargo.toml └── src │ ├── lib.rs │ ├── merkle_tree.rs │ ├── mimc.rs │ └── poseidon │ ├── mod.rs │ └── sbox.rs ├── arkworks-plonk-circuits ├── .gitignore ├── Cargo.lock ├── Cargo.toml └── src │ ├── anchor.rs │ ├── lib.rs │ ├── mixer.rs │ ├── utils.rs │ └── vanchor.rs ├── arkworks-plonk-gadgets ├── .gitignore ├── Cargo.lock ├── Cargo.toml └── src │ ├── lib.rs │ ├── merkle_tree.rs │ ├── poseidon │ ├── mod.rs │ └── sbox.rs │ └── set.rs ├── arkworks-r1cs-circuits ├── .gitignore ├── Cargo.toml └── src │ ├── anchor.rs │ ├── basic.rs │ ├── lib.rs │ ├── mixer.rs │ ├── mod.rs │ ├── poseidon.rs │ └── vanchor.rs ├── arkworks-r1cs-gadgets ├── .gitignore ├── Cargo.toml └── src │ ├── lib.rs │ ├── merkle_tree.rs │ ├── mimc.rs │ ├── poseidon │ ├── mod.rs │ └── sbox.rs │ └── set.rs ├── arkworks-setups ├── .gitignore ├── Cargo.toml └── src │ ├── aead.rs │ ├── common.rs │ ├── keypair.rs │ ├── lib.rs │ ├── plonk │ └── mod.rs │ ├── r1cs │ ├── anchor │ │ ├── mod.rs │ │ └── tests.rs │ ├── mixer │ │ ├── mod.rs │ │ └── tests.rs │ ├── mod.rs │ └── vanchor │ │ ├── mod.rs │ │ └── tests.rs │ └── utxo.rs ├── arkworks-utils ├── .gitignore ├── Cargo.toml └── src │ ├── lib.rs │ ├── mimc_params │ ├── ed_on_bn254_220.rs │ └── mod.rs │ └── poseidon_params │ ├── bls381_x17_3.rs │ ├── bls381_x17_5.rs │ ├── bls381_x3_3.rs │ ├── bls381_x3_5.rs │ ├── bls381_x5_3.rs │ ├── bls381_x5_5.rs │ ├── bn254_x17_3.rs │ ├── bn254_x17_5.rs │ ├── bn254_x3_3.rs │ ├── bn254_x3_5.rs │ ├── bn254_x5_2.rs │ ├── bn254_x5_3.rs │ ├── bn254_x5_3_result.rs │ ├── bn254_x5_4.rs │ ├── bn254_x5_5.rs │ ├── bn254_x5_5_result.rs │ ├── ed_on_bn254_x17_3.rs │ ├── ed_on_bn254_x17_5.rs │ ├── ed_on_bn254_x3_3.rs │ ├── ed_on_bn254_x3_5.rs │ ├── ed_on_bn254_x5_3.rs │ ├── ed_on_bn254_x5_5.rs │ └── mod.rs ├── assets └── webb-icon.svg ├── rust-toolchain.toml ├── rustfmt.toml └── scripts ├── bench.sh ├── build-wasm.sh ├── build.sh ├── clippy.sh ├── fmt-check.sh ├── init.sh └── test.sh /.codecov.yml: -------------------------------------------------------------------------------- 1 | 2 | 3 | # For more configuration details: 4 | # https://docs.codecov.io/docs/codecov-yaml 5 | 6 | # Check if this file is valid by running in bash: 7 | # curl -X POST --data-binary @.codecov.yml https://codecov.io/validate 8 | 9 | # Coverage configuration 10 | # ---------------------- 11 | coverage: 12 | status: 13 | patch: false 14 | 15 | range: 70..90 # First number represents red, and second represents green 16 | # (default is 70..100) 17 | round: up # up, down, or nearest 18 | precision: 2 # Number of decimal places, between 0 and 5 19 | 20 | # Ignoring Paths 21 | # -------------- 22 | # which folders/files to ignore 23 | # Ignoring for now until we can include them in workspace 24 | ignore: 25 | - arkworks-benchmarks/*/** 26 | - arkworks-plonk-circuits/*/** 27 | - arkworks-plonk-gadgets/*/** 28 | 29 | # Pull request comments: 30 | # ---------------------- 31 | # Diff is the Coverage Diff of the pull request. 32 | # Files are the files impacted by the pull request 33 | # comment: 34 | # layout: diff, files # - accepted in any order: reach, diff, flags, and/or files -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Set-Up & Build & Test 2 | 3 | # Controls when the action will run. 4 | on: 5 | push: 6 | pull_request: 7 | branches: 8 | - "**" # matches every branch 9 | - "!master" # excludes master 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | env: 15 | CARGO_TERM_COLOR: always 16 | 17 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 18 | jobs: 19 | build: 20 | # The type of runner that the job will run on 21 | runs-on: ubuntu-18.04 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v2 27 | 28 | - name: Set-Up 29 | run: ./scripts/init.sh 30 | 31 | - name: Fmt Check 32 | run: ./scripts/fmt-check.sh 33 | 34 | - name: Clippy Check 35 | run: ./scripts/clippy.sh 36 | 37 | - name: Build 38 | run: ./scripts/build.sh 39 | 40 | - name: Wasm Build 41 | run: ./scripts/build-wasm.sh 42 | 43 | - name: Test 44 | run: ./scripts/test.sh 45 | -------------------------------------------------------------------------------- /.github/workflows/coverage.yml: -------------------------------------------------------------------------------- 1 | name: check 2 | 3 | # Controls when the action will run. 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the master branch 6 | push: 7 | branches: [ master ] 8 | pull_request: 9 | branches: [ master ] 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 15 | jobs: 16 | coverage: 17 | name: coverage 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | - name: Cancel Previous Runs 22 | uses: styfle/cancel-workflow-action@0.9.1 23 | with: 24 | access_token: ${{ github.token }} 25 | 26 | - name: Checkout repository 27 | uses: actions/checkout@v2 28 | 29 | - name: Install Toolchain 30 | uses: actions-rs/toolchain@v1 31 | with: 32 | toolchain: stable 33 | override: true 34 | 35 | - name: Rust Cache 36 | uses: Swatinem/rust-cache@v1.3.0 37 | 38 | - name: Run Tarpaulin 39 | uses: actions-rs/tarpaulin@v0.1 40 | with: 41 | args: '--workspace --release --locked --out Xml --jobs 16 --timeout 5600 -- --test-threads 16' 42 | 43 | - name: Upload to codecov.io 44 | uses: codecov/codecov-action@v2 45 | with: 46 | fail_ci_if_error: true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /protocol-solidity-fixtures 3 | 4 | .idea 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "protocol-solidity-fixtures"] 2 | path = protocol-solidity-fixtures 3 | url = https://github.com/webb-tools/protocol-solidity-fixtures.git 4 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | 3 | members = [ 4 | "arkworks-native-gadgets", 5 | # R1CS gadgets + circuits 6 | "arkworks-r1cs-circuits", 7 | "arkworks-r1cs-gadgets", 8 | # Utils and setups 9 | "arkworks-setups", 10 | "arkworks-utils", 11 | ] 12 | 13 | exclude = ["arkworks-plonk-circuits", "arkworks-plonk-gadgets", "arkworks-benchmarks", "arkworks-circom-verifier", "arkworks-utils"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /arkworks-benchmarks/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /arkworks-benchmarks/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "arkworks-benchmarks" 3 | version = "1.0.0" 4 | authors = ["Webb Developers"] 5 | edition = "2018" 6 | description = "Webb protocol's zero-knowledge gadgets written using Arkworks" 7 | license = "Apache-2.0" 8 | repository = "https://github.com/webb-tools/arkworks-gadgets" 9 | homepage = "https://webb.tools" 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | arkworks-utils = { path = "../arkworks-utils", version = "1.0.0" } 15 | arkworks-r1cs-gadgets = { path = "../arkworks-r1cs-gadgets", version = "1.0.0" } 16 | arkworks-native-gadgets = { path = "../arkworks-native-gadgets", version = "1.0.0" } 17 | arkworks-r1cs-circuits = { path = "../arkworks-r1cs-circuits", version = "1.0.0" } 18 | 19 | ark-crypto-primitives = { version = "^0.3.0", features = ["r1cs"], default-features = false } 20 | ark-ff = { version = "^0.3.0", default-features = false } 21 | ark-std = { version = "^0.3.0", default-features = false } 22 | ark-r1cs-std = { version = "^0.3.0", default-features = false } 23 | ark-relations = { version = "^0.3.0", default-features = false } 24 | 25 | ark-marlin = {version = "^0.3.0", default-features = false } 26 | ark-groth16 = {version = "^0.3.0", default-features = false } 27 | blake2 = { version = "0.9", default-features = false } 28 | ark-poly-commit = { version = "^0.3.0", default-features = false } 29 | ark-poly = { version = "^0.3.0", default-features = false } 30 | ark-snark = { version = "^0.3.0", default-features = false } 31 | ark-ec = { version = "^0.3.0", default-features = false } 32 | ark-serialize = {version = "^0.3.0", default-features = false } 33 | digest = { version = "0.9" } 34 | 35 | # curves 36 | ark-ed-on-bls12-381 = { version = "^0.3.0", default-features = false, features = [ "r1cs" ] } 37 | ark-ed-on-bn254 = { version = "^0.3.0", default-features = false, features = [ "r1cs" ] } 38 | ark-bls12-381 = { version = "^0.3.0", default-features = false, features = [ "curve" ] } 39 | ark-bn254 = { version = "^0.3.0", default-features = false, features = [ "curve" ] } 40 | 41 | -------------------------------------------------------------------------------- /arkworks-benchmarks/src/main.rs: -------------------------------------------------------------------------------- 1 | use ark_bls12_381::{Bls12_381, Fr as BlsFr}; 2 | use ark_crypto_primitives::SNARK; 3 | use ark_ed_on_bls12_381::{EdwardsAffine, Fr as EdBlsFr}; 4 | use ark_ff::{One, UniformRand}; 5 | use ark_groth16::Groth16; 6 | use ark_marlin::Marlin; 7 | use ark_poly::univariate::DensePolynomial; 8 | use ark_poly_commit::{ipa_pc::InnerProductArgPC, marlin_pc::MarlinKZG10, sonic_pc::SonicKZG10}; 9 | use ark_std::{self, test_rng, time::Instant, vec::Vec}; 10 | use arkworks_native_gadgets::{ 11 | merkle_tree::SparseMerkleTree, 12 | poseidon::{FieldHasher, Poseidon}, 13 | }; 14 | use arkworks_r1cs_circuits::anchor::AnchorCircuit; 15 | use arkworks_r1cs_gadgets::poseidon::PoseidonGadget; 16 | 17 | use arkworks_utils::utils::common::{setup_params_x5_3, setup_params_x5_4}; 18 | use blake2::Blake2s; 19 | 20 | macro_rules! setup_circuit { 21 | ($test_field:ty) => {{ 22 | const ANCHOR_CT: usize = 4; 23 | const HEIGHT: usize = 30; 24 | const DEFAULT_LEAF: [u8; 32] = [0u8; 32]; 25 | 26 | type Circuit = AnchorCircuit<$test_field, PoseidonGadget<$test_field>, HEIGHT, ANCHOR_CT>; 27 | 28 | let rng = &mut test_rng(); 29 | let curve = arkworks_utils::utils::common::Curve::Bn254; 30 | // Secret inputs for the leaf 31 | let secret = <$test_field>::rand(rng); 32 | let nullifier = <$test_field>::rand(rng); 33 | // Public inputs for the leaf 34 | let chain_id = <$test_field>::one(); 35 | 36 | // Round params for the poseidon in leaf creation gadget 37 | let params4 = setup_params_x5_4(curve); 38 | let leaf_hasher = Poseidon::<$test_field>::new(params4); 39 | 40 | let params3 = setup_params_x5_3(curve); 41 | let nullifier_hasher = Poseidon::<$test_field>::new(params3); 42 | // Creating the leaf 43 | let leaf_hash = leaf_hasher.hash(&[chain_id, secret, nullifier]).unwrap(); 44 | let nullifier_hash = nullifier_hasher.hash_two(&nullifier, &nullifier).unwrap(); 45 | 46 | // Arbitrary data 47 | let arbitrary_input = <$test_field>::rand(rng); 48 | 49 | // Making params for poseidon in merkle tree 50 | 51 | let params3 = setup_params_x5_3(curve); 52 | let leaves = vec![ 53 | <$test_field>::rand(rng), 54 | <$test_field>::rand(rng), 55 | leaf_hash, 56 | <$test_field>::rand(rng), 57 | ]; 58 | let tree_hasher = Poseidon::<$test_field>::new(params3); 59 | // Making the merkle tree 60 | let mt = SparseMerkleTree::<$test_field, Poseidon<$test_field>, HEIGHT>::new_sequential( 61 | &leaves, 62 | &tree_hasher, 63 | &DEFAULT_LEAF, 64 | ) 65 | .unwrap(); 66 | // Getting the proof path 67 | let path = mt.generate_membership_proof(2); 68 | let root = mt.root(); 69 | let roots = [ 70 | <$test_field>::rand(rng), 71 | <$test_field>::rand(rng), 72 | <$test_field>::rand(rng), 73 | root.clone(), 74 | ]; 75 | let mc = Circuit::new( 76 | arbitrary_input.clone(), 77 | secret, 78 | nullifier, 79 | chain_id, 80 | roots.clone(), 81 | path, 82 | nullifier_hash, 83 | tree_hasher, 84 | leaf_hasher, 85 | ); 86 | let mut public_inputs = Vec::new(); 87 | public_inputs.push(chain_id); 88 | public_inputs.push(nullifier_hash); 89 | public_inputs.extend(roots.to_vec()); 90 | public_inputs.push(arbitrary_input); 91 | (public_inputs, mc) 92 | }}; 93 | } 94 | 95 | macro_rules! measure { 96 | ($task:block, $backend:expr, $task_name:expr, $num_iter:expr) => {{ 97 | let start = Instant::now(); 98 | for _ in 0..($num_iter - 1) { 99 | $task; 100 | } 101 | let res = $task; 102 | let end = start.elapsed(); 103 | println!( 104 | "{}: Average {} time: {:?}", 105 | $backend, 106 | $task_name, 107 | end / $num_iter 108 | ); 109 | res 110 | }}; 111 | } 112 | 113 | macro_rules! benchmark_marlin { 114 | ($marlin:ty, $field:ty, $name:expr, $nc:expr, $nv:expr, $num_iter:expr) => { 115 | let rng = &mut test_rng(); 116 | let (public_inputs, circuit) = setup_circuit!($field); 117 | 118 | // Setup 119 | let srs = measure!( 120 | { <$marlin>::universal_setup($nc, $nv, 3 * $nv, rng).unwrap() }, 121 | $name, 122 | "setup", 123 | $num_iter 124 | ); 125 | 126 | // Index 127 | let keys = measure!( 128 | { <$marlin>::index(&srs, circuit.clone()).unwrap() }, 129 | $name, 130 | "index", 131 | $num_iter 132 | ); 133 | 134 | // Prove 135 | let proof = measure!( 136 | { <$marlin>::prove(&keys.0, circuit.clone(), rng).unwrap() }, 137 | $name, 138 | "prove", 139 | $num_iter 140 | ); 141 | 142 | // verify 143 | let _ = measure!( 144 | { <$marlin>::verify(&keys.1, &public_inputs, &proof, rng).unwrap() }, 145 | $name, 146 | "verify", 147 | $num_iter 148 | ); 149 | }; 150 | } 151 | 152 | macro_rules! benchmark_groth { 153 | ($groth:ty, $field:ty, $num_iter:expr) => { 154 | let rng = &mut test_rng(); 155 | let (public_inputs, circuit) = setup_circuit!($field); 156 | 157 | // Setup 158 | let keys = measure!( 159 | { <$groth>::circuit_specific_setup(circuit.clone(), rng).unwrap() }, 160 | "Groth16", 161 | "setup", 162 | $num_iter 163 | ); 164 | 165 | // Prove 166 | let proof = measure!( 167 | { <$groth>::prove(&keys.0, circuit.clone(), rng).unwrap() }, 168 | "Groth16", 169 | "prove", 170 | $num_iter 171 | ); 172 | 173 | // verify 174 | let _ = measure!( 175 | { <$groth>::verify(&keys.1, &public_inputs, &proof).unwrap() }, 176 | "Groth16", 177 | "verify", 178 | $num_iter 179 | ); 180 | }; 181 | } 182 | 183 | fn benchmark_groth16(num_iter: u32) { 184 | type GrothSetup = Groth16; 185 | benchmark_groth!(GrothSetup, BlsFr, num_iter); 186 | } 187 | 188 | fn benchmark_marlin_poly(nc: usize, nv: usize, num_iter: u32) { 189 | type KZG10 = MarlinKZG10>; 190 | type MarlinSetup = Marlin; 191 | benchmark_marlin!(MarlinSetup, BlsFr, "Marlin_PolyKZG10", nc, nv, num_iter); 192 | } 193 | 194 | fn benchmark_marlin_sonic(nc: usize, nv: usize, num_iter: u32) { 195 | type Sonic = SonicKZG10>; 196 | type MarlinSetup = Marlin; 197 | 198 | benchmark_marlin!(MarlinSetup, BlsFr, "Marlin_Sonic", nc, nv, num_iter); 199 | } 200 | 201 | fn benchmark_marlin_ipa_pc(nc: usize, nv: usize, num_iter: u32) { 202 | type IPA = InnerProductArgPC>; 203 | type MarlinSetup = Marlin; 204 | 205 | benchmark_marlin!(MarlinSetup, EdBlsFr, "Marlin_IPA_PC", nc, nv, num_iter); 206 | } 207 | 208 | fn main() { 209 | let nc = 65536; 210 | let nv = 65536; 211 | let num_iter = 5; 212 | 213 | // Groth16 214 | benchmark_groth16(num_iter); 215 | // MarlinKZG10 216 | benchmark_marlin_poly(nc, nv, num_iter); 217 | // Sonic 218 | benchmark_marlin_sonic(nc, nv, num_iter); 219 | // IPA 220 | benchmark_marlin_ipa_pc(nc, nv, num_iter); 221 | } 222 | -------------------------------------------------------------------------------- /arkworks-native-gadgets/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /arkworks-native-gadgets/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "arkworks-native-gadgets" 3 | version = "1.0.0" 4 | authors = ["Webb Developers"] 5 | edition = "2018" 6 | description = "Webb protocol's native gadgets" 7 | license = "Apache-2.0" 8 | repository = "https://github.com/webb-tools/arkworks-gadgets" 9 | homepage = "https://webb.tools" 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | ark-ff = { version = "^0.3.0", default-features = false } 15 | ark-std = { version = "^0.3.0", default-features = false } 16 | ark-crypto-primitives = { version = "^0.3.0", features = ["r1cs"], default-features = false } 17 | 18 | [dev-dependencies] 19 | # curves 20 | ark-ed-on-bls12-381 = { version = "^0.3.0", default-features = false, features = [ "r1cs" ] } 21 | ark-ed-on-bn254 = { version = "^0.3.0", default-features = false, features = [ "r1cs" ] } 22 | ark-bn254 = { version = "^0.3.0", default-features = false } 23 | 24 | [dev-dependencies.arkworks-utils] 25 | path = "../arkworks-utils" 26 | default-features = false 27 | features = ["poseidon_bn254_x5_2", "poseidon_bn254_x5_3", "poseidon_bn254_x5_4", "poseidon_bn254_x5_5", "poseidon_bls381_x5_3", "mimc_ed_on_bn254_220"] 28 | 29 | [features] 30 | default = ["std"] 31 | std = [ 32 | "ark-std/std", 33 | "ark-ff/std", 34 | "ark-crypto-primitives/std", 35 | ] 36 | parallel = [ 37 | "ark-crypto-primitives/parallel", 38 | "ark-ff/parallel", 39 | "ark-std/parallel", 40 | ] 41 | -------------------------------------------------------------------------------- /arkworks-native-gadgets/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | 3 | use ark_ff::{BigInteger, PrimeField}; 4 | use ark_std::{boxed::Box, vec::Vec}; 5 | 6 | #[macro_use] 7 | pub extern crate ark_std; 8 | 9 | pub mod merkle_tree; 10 | pub mod mimc; 11 | pub mod poseidon; 12 | 13 | pub type Error = Box; 14 | 15 | pub mod prelude { 16 | pub use ark_crypto_primitives; 17 | pub use ark_ff; 18 | pub use ark_std; 19 | } 20 | 21 | pub fn to_field_elements(bytes: &[u8]) -> Result, Error> { 22 | let max_size_bytes = F::BigInt::NUM_LIMBS * 8; 23 | 24 | // Pad the input with zeros 25 | let padding_len = (max_size_bytes - (bytes.len() % max_size_bytes)) % max_size_bytes; 26 | let padded_input: Vec = bytes 27 | .iter() 28 | .cloned() 29 | .chain(core::iter::repeat(0u8).take(padding_len)) 30 | .collect(); 31 | 32 | let res = padded_input 33 | .chunks(max_size_bytes) 34 | .map(F::read) 35 | .collect::, _>>()?; 36 | 37 | Ok(res) 38 | } 39 | 40 | pub fn from_field_elements(elts: &[F]) -> Result, Error> { 41 | let res = elts.iter().fold(vec![], |mut acc, prev| { 42 | acc.extend_from_slice(&prev.into_repr().to_bytes_le()); 43 | acc 44 | }); 45 | 46 | Ok(res) 47 | } 48 | -------------------------------------------------------------------------------- /arkworks-native-gadgets/src/mimc.rs: -------------------------------------------------------------------------------- 1 | use crate::ark_std::string::ToString; 2 | use ark_crypto_primitives::{crh::TwoToOneCRH, Error, CRH as CRHTrait}; 3 | use ark_ff::{fields::PrimeField, BigInteger}; 4 | use ark_std::{error::Error as ArkError, marker::PhantomData, rand::Rng, vec::Vec}; 5 | 6 | use super::to_field_elements; 7 | 8 | #[derive(Debug)] 9 | pub enum MiMCError { 10 | InvalidInputs, 11 | } 12 | 13 | impl core::fmt::Display for MiMCError { 14 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 15 | use MiMCError::*; 16 | let msg = match self { 17 | InvalidInputs => "invalid inputs".to_string(), 18 | }; 19 | write!(f, "{}", msg) 20 | } 21 | } 22 | 23 | impl ArkError for MiMCError {} 24 | 25 | #[derive(Default, Clone)] 26 | pub struct MiMCParameters { 27 | pub k: F, 28 | pub rounds: usize, 29 | pub num_inputs: usize, 30 | pub num_outputs: usize, 31 | pub round_keys: Vec, 32 | } 33 | 34 | impl MiMCParameters { 35 | pub fn new( 36 | k: F, 37 | rounds: usize, 38 | num_inputs: usize, 39 | num_outputs: usize, 40 | round_keys: Vec, 41 | ) -> Self { 42 | Self { 43 | k, 44 | rounds, 45 | num_inputs, 46 | num_outputs, 47 | round_keys, 48 | } 49 | } 50 | 51 | pub fn generate(rng: &mut R) -> Self { 52 | Self { 53 | round_keys: Self::create_round_keys(rng), 54 | rounds: 220, 55 | k: F::zero(), 56 | num_inputs: 2, 57 | num_outputs: 1, 58 | } 59 | } 60 | 61 | pub fn create_round_keys(_rng: &mut R) -> Vec { 62 | todo!(); 63 | } 64 | } 65 | 66 | pub trait Rounds: Default + Clone { 67 | /// The size of the input vector 68 | const WIDTH: u8; 69 | /// Number of mimc rounds 70 | const ROUNDS: u16; 71 | } 72 | 73 | pub struct CRH { 74 | field: PhantomData, 75 | rounds: PhantomData

, 76 | } 77 | 78 | impl CRH { 79 | fn mimc(params: &MiMCParameters, state: Vec) -> Result, MiMCError> { 80 | assert!(state.len() == params.num_inputs); 81 | let mut l_out: F = F::zero(); 82 | let mut r_out: F = F::zero(); 83 | for (i, s) in state.iter().enumerate() { 84 | let l: F; 85 | let r: F; 86 | if i == 0 { 87 | l = *s; 88 | r = F::zero(); 89 | } else { 90 | l = l_out + s; 91 | r = r_out; 92 | } 93 | 94 | let res = Self::feistel(params, l, r)?; 95 | l_out = res[0]; 96 | r_out = res[1]; 97 | } 98 | 99 | let mut outs = vec![l_out]; 100 | for _ in 0..params.num_outputs { 101 | let res = Self::feistel(params, l_out, r_out)?; 102 | l_out = res[0]; 103 | r_out = res[1]; 104 | outs.push(l_out); 105 | } 106 | 107 | Ok(outs) 108 | } 109 | 110 | fn feistel(params: &MiMCParameters, left: F, right: F) -> Result<[F; 2], MiMCError> { 111 | let mut x_l = left; 112 | let mut x_r = right; 113 | let mut c: F; 114 | let mut t: F; 115 | let mut t2: F; 116 | let mut t4: F; 117 | for i in 0..params.rounds { 118 | c = if i == 0 || i == params.rounds - 1 { 119 | F::zero() 120 | } else { 121 | params.round_keys[i - 1] 122 | }; 123 | t = if i == 0 { 124 | params.k + x_l 125 | } else { 126 | params.k + x_l + c 127 | }; 128 | 129 | t2 = t * t; 130 | t4 = t2 * t2; 131 | 132 | let temp_x_l = x_l; 133 | let temp_x_r = x_r; 134 | 135 | if i < params.rounds - 1 { 136 | x_l = if i == 0 { 137 | temp_x_r 138 | } else { 139 | temp_x_r + (t4 * t) 140 | }; 141 | 142 | x_r = temp_x_l; 143 | } else { 144 | x_r = temp_x_r + (t4 * t); 145 | x_l = temp_x_l; 146 | } 147 | } 148 | 149 | Ok([x_l, x_r]) 150 | } 151 | } 152 | 153 | impl CRHTrait for CRH { 154 | type Output = F; 155 | type Parameters = MiMCParameters; 156 | 157 | const INPUT_SIZE_BITS: usize = F::BigInt::NUM_LIMBS * 8 * P::WIDTH as usize * 8; 158 | 159 | // Not sure what's the purpose of this function of we are going to pass 160 | // parameters 161 | fn setup(rng: &mut R) -> Result { 162 | Ok(Self::Parameters::generate(rng)) 163 | } 164 | 165 | fn evaluate(parameters: &Self::Parameters, input: &[u8]) -> Result { 166 | let eval_time = start_timer!(|| "PoseidonCRH::Eval"); 167 | 168 | let f_inputs: Vec = to_field_elements(input)?; 169 | 170 | if f_inputs.len() > P::WIDTH as usize { 171 | panic!( 172 | "incorrect input length {:?} for width {:?} -- input bits {:?}", 173 | f_inputs.len(), 174 | P::WIDTH, 175 | input.len() 176 | ); 177 | } 178 | 179 | let mut buffer = vec![F::zero(); P::WIDTH as usize]; 180 | buffer.iter_mut().zip(f_inputs).for_each(|(p, v)| *p = v); 181 | let result = Self::mimc(parameters, buffer)?; 182 | end_timer!(eval_time); 183 | Ok(result.get(0).cloned().ok_or(MiMCError::InvalidInputs)?) 184 | } 185 | } 186 | 187 | impl TwoToOneCRH for CRH { 188 | type Output = F; 189 | type Parameters = MiMCParameters; 190 | 191 | const LEFT_INPUT_SIZE_BITS: usize = Self::INPUT_SIZE_BITS / 2; 192 | const RIGHT_INPUT_SIZE_BITS: usize = Self::INPUT_SIZE_BITS / 2; 193 | 194 | fn setup(rng: &mut R) -> Result { 195 | ::setup(rng) 196 | } 197 | 198 | /// A simple implementation of TwoToOneCRH by asserting left and right input 199 | /// has same length and chain them together. 200 | fn evaluate( 201 | parameters: &Self::Parameters, 202 | left_input: &[u8], 203 | right_input: &[u8], 204 | ) -> Result { 205 | assert_eq!(left_input.len(), right_input.len()); 206 | assert!(left_input.len() * 8 <= Self::LEFT_INPUT_SIZE_BITS); 207 | let chained: Vec<_> = left_input 208 | .iter() 209 | .chain(right_input.iter()) 210 | .copied() 211 | .collect(); 212 | 213 | ::evaluate(parameters, &chained) 214 | } 215 | } 216 | 217 | #[cfg(test)] 218 | mod test { 219 | use super::*; 220 | use ark_ed_on_bn254::Fq; 221 | use ark_ff::{to_bytes, Zero}; 222 | use arkworks_utils::{bytes_vec_to_f, mimc_params::setup_mimc_params, Curve}; 223 | 224 | #[derive(Default, Clone)] 225 | struct MiMCRounds220; 226 | 227 | impl Rounds for MiMCRounds220 { 228 | const ROUNDS: u16 = 220; 229 | const WIDTH: u8 = 3; 230 | } 231 | 232 | type MiMC220 = CRH; 233 | 234 | pub fn setup_mimc(curve: Curve, rounds: u16, width: u8) -> MiMCParameters { 235 | let mimc_data = setup_mimc_params(curve, rounds, width).unwrap(); 236 | let constants_f = bytes_vec_to_f(&mimc_data.constants); 237 | 238 | let mimc_p = MiMCParameters { 239 | k: F::zero(), 240 | num_inputs: mimc_data.width as usize, 241 | num_outputs: mimc_data.width as usize, 242 | rounds: mimc_data.rounds as usize, 243 | round_keys: constants_f, 244 | }; 245 | 246 | mimc_p 247 | } 248 | 249 | #[test] 250 | fn test_hash() { 251 | let curve = Curve::Bn254; 252 | let params = setup_mimc(curve, MiMCRounds220::ROUNDS, MiMCRounds220::WIDTH); 253 | 254 | let inp = to_bytes![Fq::zero(), Fq::from(1u128), Fq::from(2u128)].unwrap(); 255 | 256 | let mimc_res = ::evaluate(¶ms, &inp).unwrap(); 257 | println!("{:?}", mimc_res); 258 | } 259 | } 260 | -------------------------------------------------------------------------------- /arkworks-native-gadgets/src/poseidon/sbox.rs: -------------------------------------------------------------------------------- 1 | //! The S-box used in the Poseidon hash function. 2 | //! 3 | //! The `PoseidonSbox` struct contains only one signed 8-bit integer. 4 | //! In the notation of 5 | //! [the original Poseidon paper](https://eprint.iacr.org/2019/458.pdf), 6 | //! this is alpha. 7 | //! 8 | //! The value of alpha can be either 3, 5, 17, or -1: the default is 5. 9 | //! Trying to use any other value will result in a `PoseidonError`. 10 | //! 11 | //! The `apply_sbox` method takes an element of a prime field `F` 12 | //! and raises it to the power alpha (in `F`). 13 | 14 | /// Importing dependencies 15 | use super::PoseidonError; 16 | use ark_ff::PrimeField; 17 | 18 | /// The PoseidonSbox struct contains just a public signed 8-bit integer. 19 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] 20 | pub struct PoseidonSbox(pub i8); 21 | 22 | /// The default value for PoseidonSbox is 5. 23 | impl Default for PoseidonSbox { 24 | fn default() -> Self { 25 | PoseidonSbox(5) 26 | } 27 | } 28 | 29 | impl PoseidonSbox { 30 | /// Takes in an element of a prime field and raises it to the power alpha 31 | /// (`sbox.0`) within that field. The method assumes that alpha is either 3, 32 | /// 5, 17, or -1. If not, it throws `PoseidonError`. 33 | pub fn apply_sbox(&self, elem: F) -> Result { 34 | let res = match self.0 { 35 | 3 => elem * elem * elem, 36 | 5 => { 37 | let sqr = elem.square(); 38 | sqr.square().mul(elem) 39 | } 40 | 17 => { 41 | let sqr = elem * elem; 42 | let quad = sqr * sqr; 43 | let eighth = quad * quad; 44 | let sixteenth = eighth * eighth; 45 | sixteenth * elem 46 | } 47 | -1 => elem.inverse().ok_or(PoseidonError::ApplySboxFailed)?, 48 | n => return Err(PoseidonError::InvalidSboxSize(n)), 49 | }; 50 | Ok(res) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /arkworks-plonk-circuits/.gitignore: -------------------------------------------------------------------------------- 1 | /target -------------------------------------------------------------------------------- /arkworks-plonk-circuits/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "arkworks-plonk-circuits" 3 | version = "1.0.0" 4 | authors = ["Webb Developers"] 5 | edition = "2021" 6 | description = "Webb protocol's plonk zero-knowledge circuits written using Arkworks (ark-plonk)" 7 | license = "Apache-2.0" 8 | repository = "https://github.com/webb-tools/arkworks-gadgets" 9 | homepage = "https://webb.tools" 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | arkworks-native-gadgets = { path = "../arkworks-native-gadgets", version = "1.0.0", default-features = false } 15 | arkworks-plonk-gadgets = { path = "../arkworks-plonk-gadgets", version = "1.0.0", default-features = false } 16 | 17 | plonk-core = { version = "^0.8", git = "https://github.com/ZK-Garage/plonk", features = ["trace"], default-features = false } 18 | ark-ff = { version = "^0.3.0", default-features = false } 19 | ark-std = { version = "^0.3.0", default-features = false } 20 | ark-poly-commit = { version = "^0.3.0", default-features = false } 21 | ark-poly = { version = "^0.3.0", default-features = false } 22 | ark-ec = { version = "^0.3.0", default-features = false } 23 | 24 | [dev-dependencies] 25 | # curves 26 | ark-ed-on-bn254 = { version = "^0.3.0", default-features = false, features = [ "r1cs" ] } 27 | ark-bn254 = { version = "^0.3.0", default-features = false, features = [ "curve" ] } 28 | plonk-hashing = { git = "https://github.com/ZK-Garage/plonk.git", branch = "poseidon_hash" } 29 | ark-serialize = { version = "^0.3.0", default-features = false } 30 | 31 | [dev-dependencies.arkworks-utils] 32 | path = "../arkworks-utils" 33 | default-features = false 34 | features = ["poseidon_bn254_x5_2", "poseidon_bn254_x5_3", "poseidon_bn254_x5_4", "poseidon_bn254_x5_5"] 35 | 36 | [features] 37 | default = ["std"] 38 | std = [ 39 | "ark-std/std", 40 | "arkworks-native-gadgets/std", 41 | "arkworks-plonk-gadgets/std", 42 | "ark-ff/std", 43 | "ark-ec/std", 44 | "ark-poly-commit/std", 45 | "ark-poly/std", 46 | ] 47 | -------------------------------------------------------------------------------- /arkworks-plonk-circuits/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | 3 | #[macro_use] 4 | pub extern crate ark_std; 5 | 6 | pub mod anchor; 7 | pub mod mixer; 8 | pub mod utils; 9 | pub mod vanchor; 10 | -------------------------------------------------------------------------------- /arkworks-plonk-gadgets/.gitignore: -------------------------------------------------------------------------------- 1 | /target -------------------------------------------------------------------------------- /arkworks-plonk-gadgets/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "arkworks-plonk-gadgets" 3 | version = "1.0.0" 4 | authors = ["Webb Developers"] 5 | edition = "2021" 6 | description = "Webb protocol's plonk zero-knowledge gadgets written using Arkworks (ark-plonk)" 7 | license = "Apache-2.0" 8 | repository = "https://github.com/webb-tools/arkworks-gadgets" 9 | homepage = "https://webb.tools" 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | arkworks-native-gadgets = { path = "../arkworks-native-gadgets", version = "1.0.0", default-features = false } 15 | 16 | ark-ff = { version = "^0.3.0", default-features = false } 17 | ark-std = { version = "^0.3.0", default-features = false } 18 | plonk-core = { version = "^0.8", git = "https://github.com/ZK-Garage/plonk", features = ["trace"], default-features = false } 19 | ark-ec = { version = "^0.3.0", default-features = false } 20 | 21 | [dev-dependencies] 22 | plonk-hashing = { git = "https://github.com/ZK-Garage/plonk.git", branch = "poseidon_hash" } 23 | ark-poly-commit = { version = "^0.3.0", default-features = false } 24 | ark-poly = { version = "^0.3.0", default-features = false } 25 | ark-serialize = { version = "^0.3.0", default-features = false } 26 | 27 | # curves 28 | ark-ed-on-bn254 = { version = "^0.3.0", default-features = false, features = [ "r1cs" ] } 29 | ark-bn254 = { version = "^0.3.0", default-features = false, features = [ "curve" ] } 30 | 31 | [dev-dependencies.arkworks-utils] 32 | path = "../arkworks-utils" 33 | default-features = false 34 | features = ["poseidon_bn254_x5_3"] 35 | 36 | [features] 37 | default = ["std"] 38 | std = [ 39 | "ark-std/std", 40 | "arkworks-native-gadgets/std", 41 | "ark-ff/std", 42 | "ark-ec/std", 43 | ] 44 | -------------------------------------------------------------------------------- /arkworks-plonk-gadgets/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | 3 | #[macro_use] 4 | pub extern crate ark_std; 5 | 6 | pub mod merkle_tree; 7 | pub mod poseidon; 8 | pub mod set; 9 | 10 | use ark_ec::models::TEModelParameters; 11 | use ark_ff::PrimeField; 12 | use ark_std::vec::Vec; 13 | use plonk_core::{constraint_system::StandardComposer, prelude::Variable}; 14 | 15 | /// Add a variable to a circuit and constrain it to a public input value that 16 | /// is expected to be different in each instance of the circuit. 17 | pub fn add_public_input_variable(composer: &mut StandardComposer, value: F) -> Variable 18 | where 19 | F: PrimeField, 20 | P: TEModelParameters, 21 | { 22 | let variable = composer.add_input(value); 23 | composer.poly_gate( 24 | variable, 25 | variable, 26 | variable, 27 | F::zero(), 28 | -F::one(), 29 | F::zero(), 30 | F::zero(), 31 | F::zero(), 32 | Some(value), 33 | ); 34 | variable 35 | } 36 | 37 | pub fn add_public_input_variables( 38 | composer: &mut StandardComposer, 39 | items: Vec, 40 | ) -> Vec 41 | where 42 | F: PrimeField, 43 | P: TEModelParameters, 44 | { 45 | let mut vars = Vec::new(); 46 | for item in items { 47 | vars.push(add_public_input_variable(composer, item)); 48 | } 49 | vars 50 | } 51 | -------------------------------------------------------------------------------- /arkworks-plonk-gadgets/src/poseidon/sbox.rs: -------------------------------------------------------------------------------- 1 | use ark_ec::TEModelParameters; 2 | use ark_ff::PrimeField; 3 | use arkworks_native_gadgets::poseidon::sbox::PoseidonSbox; 4 | use plonk_core::{constraint_system::StandardComposer, error::Error, prelude::Variable}; 5 | 6 | pub trait SboxConstraints { 7 | fn synthesize_sbox>( 8 | &self, 9 | input: &Variable, 10 | composer: &mut StandardComposer, 11 | ) -> Result; 12 | } 13 | 14 | impl SboxConstraints for PoseidonSbox { 15 | fn synthesize_sbox>( 16 | &self, 17 | input_var: &Variable, 18 | composer: &mut StandardComposer, 19 | ) -> Result { 20 | match self { 21 | PoseidonSbox(val) => match val { 22 | 3 => synthesize_exp3_sbox::(input_var, composer), 23 | 5 => synthesize_exp5_sbox::(input_var, composer), 24 | 17 => synthesize_exp17_sbox::(input_var, composer), 25 | _ => synthesize_exp3_sbox::(input_var, composer), 26 | }, 27 | _ => synthesize_exp3_sbox::(input_var, composer), 28 | } 29 | } 30 | } 31 | 32 | // Allocate variables in circuit and enforce constraints when Sbox as cube 33 | fn synthesize_exp3_sbox>( 34 | input_var: &Variable, 35 | composer: &mut StandardComposer, 36 | ) -> Result { 37 | let sqr = 38 | composer.arithmetic_gate(|gate| gate.witness(*input_var, *input_var, None).mul(F::one())); 39 | let cube = composer.arithmetic_gate(|gate| gate.witness(sqr, *input_var, None).mul(F::one())); 40 | Ok(cube) 41 | } 42 | 43 | // Allocate variables in circuit and enforce constraints when Sbox as cube 44 | fn synthesize_exp5_sbox>( 45 | input_var: &Variable, 46 | composer: &mut StandardComposer, 47 | ) -> Result { 48 | let sqr = 49 | composer.arithmetic_gate(|gate| gate.witness(*input_var, *input_var, None).mul(F::one())); 50 | let fourth = composer.arithmetic_gate(|gate| gate.witness(sqr, sqr, None).mul(F::one())); 51 | let fifth = 52 | composer.arithmetic_gate(|gate| gate.witness(fourth, *input_var, None).mul(F::one())); 53 | Ok(fifth) 54 | } 55 | 56 | // Allocate variables in circuit and enforce constraints when Sbox as cube 57 | fn synthesize_exp17_sbox>( 58 | input_var: &Variable, 59 | composer: &mut StandardComposer, 60 | ) -> Result { 61 | let sqr = 62 | composer.arithmetic_gate(|gate| gate.witness(*input_var, *input_var, None).mul(F::one())); 63 | let fourth = composer.arithmetic_gate(|gate| gate.witness(sqr, sqr, None).mul(F::one())); 64 | let eigth = composer.arithmetic_gate(|gate| gate.witness(fourth, fourth, None).mul(F::one())); 65 | let sixteenth = composer.arithmetic_gate(|gate| gate.witness(eigth, eigth, None).mul(F::one())); 66 | let seventeenth = 67 | composer.arithmetic_gate(|gate| gate.witness(sixteenth, *input_var, None).mul(F::one())); 68 | Ok(seventeenth) 69 | } 70 | -------------------------------------------------------------------------------- /arkworks-plonk-gadgets/src/set.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Webb and was adapted from Arkworks. 2 | // 3 | // Copyright (C) 2021 Webb Technologies Inc. 4 | // SPDX-License-Identifier: Apache-2.0 5 | // 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! A Plonk gadget to check membership within a set. 19 | //! 20 | //! To check whether an element `x` is in a set `A`, the gadget takes the 21 | //! difference between `x` and every element of `A`, takes the product of 22 | //! all those differences, and checks if it is equal to zero. The product 23 | //! is zero if and only if `x` is in `A`; however, the individual 24 | //! elements of `A` are not revealed, making it zero-knowledge. 25 | //! 26 | //! For example, one could check if a certain Merkle root hash is a member 27 | //! of a set of Merkle root hashes. 28 | 29 | use ark_ec::models::TEModelParameters; 30 | use ark_ff::PrimeField; 31 | use ark_std::{marker::PhantomData, vec::Vec}; 32 | use plonk_core::{constraint_system::StandardComposer, prelude::Variable}; 33 | 34 | use crate::add_public_input_variables; 35 | 36 | pub struct SetGadget> { 37 | items: Vec, 38 | te: PhantomData

, 39 | } 40 | 41 | impl> SetGadget { 42 | pub fn from_native(composer: &mut StandardComposer, items: Vec) -> Self { 43 | let vars = add_public_input_variables(composer, items); 44 | 45 | Self { 46 | items: vars, 47 | te: PhantomData, 48 | } 49 | } 50 | 51 | /// A function whose output is 1 if `member` belongs to `set` 52 | /// and 0 otherwise. Contraints are added to a StandardComposer 53 | /// and the output is added as a variable to the StandardComposer. 54 | /// The set is assumed to consist of public inputs, such as roots 55 | /// of various Merkle trees. 56 | pub fn check_set_membership( 57 | &self, 58 | composer: &mut StandardComposer, 59 | member: Variable, 60 | ) -> Variable { 61 | // Compute all differences between `member` and set elements 62 | let mut diffs = Vec::new(); 63 | for x in self.items.iter() { 64 | let diff = composer 65 | .arithmetic_gate(|gate| gate.witness(member, *x, None).add(F::one(), -F::one())); 66 | diffs.push(diff); 67 | } 68 | 69 | // Accumulate the product of all differences 70 | let mut accumulator = composer.add_witness_to_circuit_description(F::one()); 71 | for diff in diffs { 72 | accumulator = composer 73 | .arithmetic_gate(|gate| gate.witness(accumulator, diff, None).mul(F::one())); 74 | } 75 | 76 | composer.is_zero_with_output(accumulator) 77 | } 78 | 79 | /// Similar to the check_set_membership function, 80 | /// except that it accepts an `is_enabled` argument 81 | /// that turns the set membership check on/off. 82 | /// Intended usage is when verifying input UTXOs: the 83 | /// validity of an input only needs to be verified if 84 | /// its amount is non-zero, so adding the input amount 85 | /// as the `is_enabled` argument is a way of turning the 86 | /// set membership check on only when it is needed. 87 | pub fn check_set_membership_is_enabled( 88 | &self, 89 | composer: &mut StandardComposer, 90 | member: Variable, 91 | is_enabled: Variable, 92 | ) -> Variable { 93 | // Compute all differences between `member` and set elements 94 | let mut diffs = Vec::new(); 95 | for x in self.items.iter() { 96 | let diff = composer 97 | .arithmetic_gate(|gate| gate.witness(member, *x, None).add(F::one(), -F::one())); 98 | diffs.push(diff); 99 | } 100 | 101 | // Accumulate the product of all differences 102 | let mut accumulator = composer.add_witness_to_circuit_description(F::one()); 103 | for diff in diffs { 104 | accumulator = composer 105 | .arithmetic_gate(|gate| gate.witness(accumulator, diff, None).mul(F::one())); 106 | } 107 | // Multiply accumulated product by `is_enabled` 108 | accumulator = composer 109 | .arithmetic_gate(|gate| gate.witness(accumulator, is_enabled, None).mul(F::one())); 110 | 111 | composer.is_zero_with_output(accumulator) 112 | } 113 | } 114 | 115 | #[cfg(test)] 116 | pub(crate) mod tests { 117 | //copied from ark-plonk 118 | use super::*; 119 | use ark_ed_on_bn254::{EdwardsParameters as JubjubParameters, Fq}; 120 | 121 | #[test] 122 | fn test_verify_set_membership_functions() { 123 | let set = vec![Fq::from(1u32), Fq::from(2u32), Fq::from(3u32)]; 124 | let mut composer = StandardComposer::::new(); 125 | 126 | let set_gadget = SetGadget::from_native(&mut composer, set); 127 | 128 | let one = composer.add_input(Fq::from(1u32)); 129 | let member = composer.add_input(Fq::from(2u32)); 130 | 131 | let result_private = set_gadget.check_set_membership(&mut composer, member); 132 | composer.assert_equal(result_private, one); 133 | composer.check_circuit_satisfied(); 134 | } 135 | 136 | #[test] 137 | fn test_fail_to_verify_set_membership_functions() { 138 | let set = vec![Fq::from(1u32), Fq::from(2u32), Fq::from(3u32)]; 139 | let mut composer = StandardComposer::::new(); 140 | 141 | let set_gadget = SetGadget::from_native(&mut composer, set); 142 | 143 | let zero = composer.zero_var(); 144 | let member = composer.add_input(Fq::from(4u32)); 145 | 146 | let result_private = set_gadget.check_set_membership(&mut composer, member); 147 | composer.assert_equal(result_private, zero); 148 | composer.check_circuit_satisfied(); 149 | } 150 | 151 | #[test] 152 | fn test_verify_set_membership_enabled_functions() { 153 | let set = vec![Fq::from(1u32), Fq::from(2u32), Fq::from(3u32)]; 154 | let mut composer = StandardComposer::::new(); 155 | 156 | let set_gadget = SetGadget::from_native(&mut composer, set); 157 | 158 | let one = composer.add_input(Fq::from(1u32)); 159 | // This is not a member of the set 160 | let member = composer.add_input(Fq::from(4u32)); 161 | // We set `is_enabled` to 0, so check should pass 162 | let is_enabled = composer.add_input(Fq::from(0u32)); 163 | 164 | let result_private = 165 | set_gadget.check_set_membership_is_enabled(&mut composer, member, is_enabled); 166 | composer.assert_equal(result_private, one); 167 | composer.check_circuit_satisfied(); 168 | } 169 | 170 | #[test] 171 | fn test_fail_to_verify_set_membership_enabled_functions() { 172 | let set = vec![Fq::from(1u32), Fq::from(2u32), Fq::from(3u32)]; 173 | let mut composer = StandardComposer::::new(); 174 | 175 | let set_gadget = SetGadget::from_native(&mut composer, set); 176 | 177 | let zero = composer.zero_var(); 178 | // This is not a member of the set 179 | let member = composer.add_input(Fq::from(4u32)); 180 | // We set `is_enabled` to 1, so check should fail 181 | let is_enabled = composer.add_input(Fq::from(1u32)); 182 | 183 | let result_private = 184 | set_gadget.check_set_membership_is_enabled(&mut composer, member, is_enabled); 185 | composer.assert_equal(result_private, zero); 186 | composer.check_circuit_satisfied(); 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /arkworks-r1cs-circuits/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /arkworks-r1cs-circuits/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "arkworks-r1cs-circuits" 3 | version = "1.0.0" 4 | authors = ["Webb Developers"] 5 | edition = "2018" 6 | description = "Webb protocol's r1cs zero-knowledge circuits written using Arkworks" 7 | license = "Apache-2.0" 8 | repository = "https://github.com/webb-tools/arkworks-gadgets" 9 | homepage = "https://webb.tools" 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | arkworks-r1cs-gadgets = { path = "../arkworks-r1cs-gadgets", version = "1.0.0", default-features = false } 15 | arkworks-native-gadgets = { path = "../arkworks-native-gadgets", version = "1.0.0", default-features = false } 16 | 17 | ark-ff = { version = "^0.3.0", default-features = false } 18 | ark-std = { version = "^0.3.0", default-features = false } 19 | ark-r1cs-std = { version = "^0.3.0", default-features = false } 20 | ark-relations = { version = "^0.3.0", default-features = false } 21 | 22 | [dev-dependencies] 23 | ark-crypto-primitives = { version = "^0.3.0", features = ["r1cs"], default-features = false } 24 | ark-marlin = { version = "^0.3.0", default-features = false } 25 | ark-groth16 = { version = "^0.3.0", default-features = false } 26 | ark-poly-commit = { version = "^0.3.0", default-features = false } 27 | ark-poly = { version = "^0.3.0", default-features = false } 28 | ark-snark = { version = "^0.3.0", default-features = false } 29 | 30 | blake2 = { version = "0.9", default-features = false } 31 | digest = { version = "0.9" } 32 | 33 | # curves 34 | ark-ed-on-bn254 = { version = "^0.3.0", default-features = false, features = [ "r1cs" ] } 35 | ark-bls12-381 = { version = "^0.3.0", default-features = false, features = [ "curve" ] } 36 | 37 | [dev-dependencies.arkworks-utils] 38 | path = "../arkworks-utils" 39 | default-features = false 40 | features = ["poseidon_bn254_x5_2", "poseidon_bn254_x5_3", "poseidon_bn254_x5_4", "poseidon_bn254_x5_5", "poseidon_bls381_x5_3"] 41 | 42 | [features] 43 | default = ["std"] 44 | std = [ 45 | "ark-std/std", 46 | "arkworks-r1cs-gadgets/std", 47 | "arkworks-native-gadgets/std", 48 | "ark-ff/std", 49 | "ark-r1cs-std/std", 50 | "ark-relations/std", 51 | ] 52 | parallel = [ 53 | "ark-ff/parallel", 54 | "ark-std/parallel", 55 | "ark-r1cs-std/parallel", 56 | ] 57 | 58 | -------------------------------------------------------------------------------- /arkworks-r1cs-circuits/src/anchor.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Webb. 2 | 3 | // Copyright (C) 2021 Webb Technologies Inc. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! The Anchor is a cross-chain fixed sized deposit/withdraw shielded pool. 19 | //! It allows for users to deposit tokens on one chain and withdraw in another 20 | //! one without linking the deposit to the withdrawal. 21 | 22 | //! We will take inputs and do a merkle tree reconstruction for each node in the 23 | //! path and check if the reconstructed root is inside the current root set. 24 | //! 25 | //! This is the Groth16 setup implementation of Anchor 26 | use ark_ff::fields::PrimeField; 27 | use ark_r1cs_std::{eq::EqGadget, fields::fp::FpVar, prelude::*}; 28 | use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}; 29 | use ark_std::vec::Vec; 30 | use arkworks_native_gadgets::merkle_tree::Path; 31 | use arkworks_r1cs_gadgets::{merkle_tree::PathVar, poseidon::FieldHasherGadget, set::SetGadget}; 32 | 33 | /// Defines an `AnchorCircuit` struct that hold all the information thats needed 34 | /// to verify the following statements: 35 | /// * Alice knows a witness tuple `(secret, nullifier, merklePath)` 36 | /// and a commitment `Hash(chain_id, nullifier, secret)` stored in one of the 37 | /// Anchor merkle trees, 38 | /// * The Anchor smart contract / end-user application hasn't seen this 39 | /// `nullifier_hash` before. 40 | /// 41 | /// Needs to implement `ConstraintSynthesizer` and a 42 | /// constructor to generate proper constraints 43 | #[derive(Clone)] 44 | pub struct AnchorCircuit, const N: usize, const M: usize> { 45 | // Represents the hash of 46 | // recepient + relayer + fee + refunds + commitment 47 | arbitrary_input: F, 48 | // secret 49 | secret: F, 50 | // nullifier to prevent double spending 51 | nullifier: F, 52 | // source chain_id 53 | chain_id: F, 54 | // Merkle root set to use on one-of-many proof 55 | root_set: [F; M], 56 | // Merkle path to transaction 57 | path: Path, 58 | nullifier_hash: F, 59 | // 3 input hasher 60 | hasher3: HG::Native, 61 | // 4 input hasher 62 | hasher4: HG::Native, 63 | } 64 | 65 | /// A constructor for the `AnchorCircuit` 66 | impl AnchorCircuit 67 | where 68 | F: PrimeField, 69 | HG: FieldHasherGadget, 70 | { 71 | #[allow(clippy::too_many_arguments)] 72 | pub fn new( 73 | arbitrary_input: F, 74 | secret: F, 75 | nullifier: F, 76 | chain_id: F, 77 | root_set: [F; M], 78 | path: Path, 79 | nullifier_hash: F, 80 | hasher3: HG::Native, 81 | hasher4: HG::Native, 82 | ) -> Self { 83 | Self { 84 | arbitrary_input, 85 | secret, 86 | nullifier, 87 | chain_id, 88 | root_set, 89 | path, 90 | nullifier_hash, 91 | hasher3, 92 | hasher4, 93 | } 94 | } 95 | } 96 | 97 | /// Implementation of the `ConstraintSynthesizer` trait for the `AnchorCircuit` 98 | /// https://github.com/arkworks-rs/snark/blob/master/relations/src/r1cs/constraint_system.rs 99 | /// 100 | /// This is the main function that is called by the `R1CS` library to generate 101 | /// the constraints for the `AnchorCircuit`. 102 | impl ConstraintSynthesizer for AnchorCircuit 103 | where 104 | F: PrimeField, 105 | HG: FieldHasherGadget, 106 | { 107 | fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { 108 | let arbitrary_input = self.arbitrary_input; 109 | let secret = self.secret; 110 | let nullifier = self.nullifier; 111 | let chain_id = self.chain_id; 112 | let root_set = self.root_set; 113 | let path = self.path; 114 | let nullifier_hash = self.nullifier_hash; 115 | 116 | // Generating vars 117 | // Public inputs 118 | let nullifier_hash_var = FpVar::::new_input(cs.clone(), || Ok(nullifier_hash))?; 119 | let arbitrary_input_var = FpVar::::new_input(cs.clone(), || Ok(arbitrary_input))?; 120 | let chain_id_var = FpVar::::new_input(cs.clone(), || Ok(chain_id))?; 121 | let roots_var = Vec::>::new_input(cs.clone(), || Ok(root_set))?; 122 | 123 | // Hashers 124 | let hasher3_gadget: HG = 125 | FieldHasherGadget::::from_native(&mut cs.clone(), self.hasher3)?; 126 | let hasher4_gadget: HG = 127 | FieldHasherGadget::::from_native(&mut cs.clone(), self.hasher4)?; 128 | 129 | // Private inputs 130 | let secret_var = FpVar::::new_witness(cs.clone(), || Ok(secret))?; 131 | let nullifier_var = FpVar::::new_witness(cs.clone(), || Ok(nullifier))?; 132 | let path_var = PathVar::::new_witness(cs.clone(), || Ok(path))?; 133 | 134 | // Creating the leaf and checking the membership inside the tree 135 | let anchor_leaf = 136 | hasher4_gadget.hash(&[chain_id_var, nullifier_var.clone(), secret_var])?; 137 | let anchor_nullifier = hasher3_gadget.hash_two(&nullifier_var, &nullifier_var)?; 138 | let root_var = path_var.root_hash(&anchor_leaf, &hasher3_gadget)?; 139 | // Check if target root is in set 140 | let set_gadget = SetGadget::new(roots_var); 141 | let is_set_member = set_gadget.check_membership(&root_var)?; 142 | // Constraining arbitrary inputs 143 | let _ = &arbitrary_input_var * &arbitrary_input_var; 144 | 145 | // Enforcing constraints 146 | is_set_member.enforce_equal(&Boolean::TRUE)?; 147 | anchor_nullifier.enforce_equal(&nullifier_hash_var)?; 148 | 149 | Ok(()) 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /arkworks-r1cs-circuits/src/basic.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Webb. 2 | 3 | // Copyright (C) 2021 Webb Technologies Inc. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! Dummy example to show how interfaces should be used 19 | use ark_ff::PrimeField; 20 | use ark_relations::{ 21 | lc, 22 | r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}, 23 | }; 24 | 25 | /// Defines `DummyCircuit` 26 | #[derive(Copy)] 27 | struct DummyCircuit { 28 | pub a: Option, 29 | pub b: Option, 30 | pub num_variables: usize, 31 | pub num_constraints: usize, 32 | } 33 | 34 | /// constructor for DummyCircuit 35 | impl Clone for DummyCircuit { 36 | fn clone(&self) -> Self { 37 | DummyCircuit { 38 | a: self.a, 39 | b: self.b, 40 | num_variables: self.num_variables, 41 | num_constraints: self.num_constraints, 42 | } 43 | } 44 | } 45 | 46 | /// Implementation of the `ConstraintSynthesizer` trait for the `DummyCircuit` 47 | /// https://github.com/arkworks-rs/snark/blob/master/relations/src/r1cs/constraint_system.rs 48 | /// 49 | /// This is the main function that is called by the `R1CS` library to generate 50 | /// the constraints for the `DummyCircuit`. 51 | impl ConstraintSynthesizer for DummyCircuit { 52 | fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { 53 | let a = cs.new_witness_variable(|| self.a.ok_or(SynthesisError::AssignmentMissing))?; 54 | let b = cs.new_witness_variable(|| self.b.ok_or(SynthesisError::AssignmentMissing))?; 55 | let c = cs.new_input_variable(|| { 56 | let a = self.a.ok_or(SynthesisError::AssignmentMissing)?; 57 | let b = self.b.ok_or(SynthesisError::AssignmentMissing)?; 58 | 59 | Ok(a * b) 60 | })?; 61 | 62 | for _ in 0..self.num_constraints { 63 | cs.enforce_constraint(lc!() + a, lc!() + b, lc!() + c)?; 64 | } 65 | 66 | Ok(()) 67 | } 68 | } 69 | 70 | #[cfg(test)] 71 | mod test { 72 | use super::*; 73 | use ark_bls12_381::{Bls12_381, Fr as BlsFr}; 74 | use ark_ed_on_bn254::{EdwardsAffine, Fr as BabyJubJub}; 75 | use ark_groth16::Groth16; 76 | use ark_marlin::Marlin; 77 | use ark_poly::univariate::DensePolynomial; 78 | use ark_poly_commit::{ipa_pc::InnerProductArgPC, marlin_pc::MarlinKZG10}; 79 | use ark_snark::SNARK; 80 | use ark_std::{ops::*, UniformRand}; 81 | use blake2::Blake2s; 82 | 83 | #[test] 84 | fn should_verify_basic_circuit() { 85 | let rng = &mut ark_std::test_rng(); 86 | 87 | let nc = 3; 88 | let nv = 3; 89 | let c = DummyCircuit:: { 90 | a: Some(BlsFr::rand(rng)), 91 | b: Some(BlsFr::rand(rng)), 92 | num_variables: nv, 93 | num_constraints: nc, 94 | }; 95 | 96 | type KZG10 = MarlinKZG10>; 97 | type MarlinSetup = Marlin; 98 | 99 | let srs = MarlinSetup::universal_setup(nc, nv, nv, rng).unwrap(); 100 | let (pk, vk) = MarlinSetup::index(&srs, c).unwrap(); 101 | let proof = MarlinSetup::prove(&pk, c.clone(), rng).unwrap(); 102 | 103 | let v = c.a.unwrap().mul(c.b.unwrap()); 104 | 105 | let res = MarlinSetup::verify(&vk, &vec![v], &proof, rng).unwrap(); 106 | assert!(res); 107 | } 108 | 109 | #[test] 110 | fn should_verify_basic_ipa_circuit() { 111 | let rng = &mut ark_std::test_rng(); 112 | 113 | let nc = 3; 114 | let nv = 3; 115 | let c = DummyCircuit:: { 116 | a: Some(BabyJubJub::rand(rng)), 117 | b: Some(BabyJubJub::rand(rng)), 118 | num_variables: nv, 119 | num_constraints: nc, 120 | }; 121 | 122 | type UniPoly = DensePolynomial; 123 | type IPA = InnerProductArgPC; 124 | type MarlinSetup = Marlin; 125 | 126 | let srs = MarlinSetup::universal_setup(nc, nc, nc, rng).unwrap(); 127 | let (pk, vk) = MarlinSetup::index(&srs, c).unwrap(); 128 | let proof = MarlinSetup::prove(&pk, c, rng).unwrap(); 129 | 130 | let v = c.a.unwrap().mul(c.b.unwrap()); 131 | 132 | let res = MarlinSetup::verify(&vk, &vec![v], &proof, rng).unwrap(); 133 | assert!(res); 134 | } 135 | 136 | #[test] 137 | fn should_verify_basic_circuit_groth16() { 138 | let rng = &mut ark_std::test_rng(); 139 | let c = DummyCircuit:: { 140 | a: Some(BlsFr::rand(rng)), 141 | b: Some(BlsFr::rand(rng)), 142 | num_variables: 0, 143 | num_constraints: 3, 144 | }; 145 | 146 | let (pk, vk) = Groth16::::circuit_specific_setup(c, rng).unwrap(); 147 | let proof = Groth16::::prove(&pk, c.clone(), rng).unwrap(); 148 | 149 | let v = c.a.unwrap().mul(c.b.unwrap()); 150 | 151 | let res = Groth16::::verify(&vk, &vec![v], &proof).unwrap(); 152 | assert!(res); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /arkworks-r1cs-circuits/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Webb. 2 | 3 | // Copyright (C) 2021 Webb Technologies Inc. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | #![cfg_attr(not(feature = "std"), no_std)] 19 | 20 | #[macro_use] 21 | pub extern crate ark_std; 22 | 23 | use ark_std::boxed::Box; 24 | 25 | pub mod anchor; 26 | pub mod basic; 27 | pub mod mixer; 28 | pub mod poseidon; 29 | pub mod vanchor; 30 | 31 | pub type Error = Box; 32 | 33 | pub mod prelude { 34 | pub use ark_ff; 35 | pub use ark_std; 36 | } 37 | -------------------------------------------------------------------------------- /arkworks-r1cs-circuits/src/mixer.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Webb. 2 | 3 | // Copyright (C) 2021 Webb Technologies Inc. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! The Mixer is a fixed sized deposit/withdraw shielded pool. 19 | //! This is the simplest circuit in arkworks-circuits. 20 | //! It implements a on-chain mixer contract that allows for users to deposit 21 | //! tokens using one wallet and withdraw using another one. This system uses 22 | //! zero-knowledge proofs so no private information about the user gets leaked. 23 | //! 24 | //! Will take inputs and do a merkle tree reconstruction for each node in the 25 | //! path to check if the reconstructed root matches current merkle root. 26 | //! 27 | //! This is the Groth16 setup implementation of the Mixer 28 | use ark_ff::fields::PrimeField; 29 | use ark_r1cs_std::{eq::EqGadget, fields::fp::FpVar, prelude::*}; 30 | use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}; 31 | use arkworks_native_gadgets::merkle_tree::Path; 32 | use arkworks_r1cs_gadgets::{merkle_tree::PathVar, poseidon::FieldHasherGadget}; 33 | 34 | /// Defines a `MixerCircuit` struct that hold all the information thats needed 35 | /// to verify the following statement: 36 | 37 | /// * Alice knows a witness tuple `(secret, nullifier, merklePath)` and a 38 | /// commitment `Hash(secret, nullifier)` that is stored in the merkle tree. 39 | /// 40 | /// Needs to implement `ConstraintSynthesizer` and a 41 | /// constructor to generate proper constraints 42 | #[derive(Clone)] 43 | pub struct MixerCircuit, const N: usize> { 44 | // Represents the hash of recepient + relayer + fee + refunds + commitment 45 | arbitrary_input: F, 46 | // Secret 47 | secret: F, 48 | // Nullifier to prevent double spending 49 | nullifier: F, 50 | // Merkle path to transaction 51 | path: Path, 52 | // Merkle root with transaction in it 53 | root: F, 54 | // Nullifier hash to prevent double spending 55 | nullifier_hash: F, 56 | // Hasher to be used inside the circuit 57 | hasher: HG::Native, 58 | } 59 | 60 | /// Constructor for MixerCircuit 61 | impl MixerCircuit 62 | where 63 | F: PrimeField, 64 | HG: FieldHasherGadget, 65 | { 66 | pub fn new( 67 | arbitrary_input: F, 68 | secret: F, 69 | nullifier: F, 70 | path: Path, 71 | root: F, 72 | nullifier_hash: F, 73 | hasher: HG::Native, 74 | ) -> Self { 75 | Self { 76 | arbitrary_input, 77 | secret, 78 | nullifier, 79 | path, 80 | root, 81 | nullifier_hash, 82 | hasher, 83 | } 84 | } 85 | } 86 | /// Implementation of the `ConstraintSynthesizer` trait for the `MixerCircuit` 87 | /// https://github.com/arkworks-rs/snark/blob/master/relations/src/r1cs/constraint_system.rs 88 | /// 89 | /// This is the main function that is called by the `R1CS` library to generate 90 | /// the constraints for the `AnchorCircuit`. 91 | impl ConstraintSynthesizer for MixerCircuit 92 | where 93 | F: PrimeField, 94 | HG: FieldHasherGadget, 95 | { 96 | fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { 97 | let arbitrary_input = self.arbitrary_input; 98 | let secret = self.secret; 99 | let nullifier = self.nullifier; 100 | let path = self.path; 101 | let root = self.root; 102 | let nullifier_hash = self.nullifier_hash; 103 | 104 | // Generating vars 105 | // Public inputs 106 | let nullifier_hash_var = FpVar::::new_input(cs.clone(), || Ok(nullifier_hash))?; 107 | let root_var = FpVar::::new_input(cs.clone(), || Ok(root))?; 108 | let arbitrary_input_var = FpVar::::new_input(cs.clone(), || Ok(arbitrary_input))?; 109 | 110 | // Hashers 111 | let hasher: HG = FieldHasherGadget::::from_native(&mut cs.clone(), self.hasher)?; 112 | 113 | // Private inputs 114 | let secret_var = FpVar::::new_witness(cs.clone(), || Ok(secret))?; 115 | let nullifier_var = FpVar::::new_witness(cs.clone(), || Ok(nullifier))?; 116 | let path_var = PathVar::::new_witness(cs.clone(), || Ok(path))?; 117 | 118 | // Creating the leaf and checking the membership inside the tree 119 | let mixer_leaf_hash: FpVar = hasher.hash_two(&secret_var, &nullifier_var)?; 120 | let mixer_nullifier_hash = hasher.hash_two(&nullifier_var, &nullifier_var)?; 121 | 122 | let is_member = path_var.check_membership(&root_var, &mixer_leaf_hash, &hasher)?; 123 | // Constraining arbitrary inputs 124 | let _ = &arbitrary_input_var * &arbitrary_input_var; 125 | 126 | // Enforcing constraints 127 | is_member.enforce_equal(&Boolean::TRUE)?; 128 | mixer_nullifier_hash.enforce_equal(&nullifier_hash_var)?; 129 | 130 | Ok(()) 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /arkworks-r1cs-circuits/src/mod.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Webb. 2 | 3 | // Copyright (C) 2021 Webb Technologies Inc. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | pub mod anchor; 19 | pub mod basic; 20 | pub mod mixer; 21 | pub mod poseidon; 22 | pub mod vanchor; 23 | -------------------------------------------------------------------------------- /arkworks-r1cs-circuits/src/poseidon.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Webb. 2 | 3 | // Copyright (C) 2021 Webb Technologies Inc. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | //! Poseidon hasher circuit to prove Hash(a, b) == c 19 | //! 20 | //! This is the Groth16 setup implementation of Poseidon 21 | use ark_ff::PrimeField; 22 | use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget, fields::fp::FpVar}; 23 | use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}; 24 | use arkworks_r1cs_gadgets::poseidon::FieldHasherGadget; 25 | 26 | #[derive(Copy)] 27 | struct PoseidonCircuit> { 28 | pub a: F, 29 | pub b: F, 30 | pub c: F, 31 | hasher: HG::Native, 32 | } 33 | 34 | /// Constructor for PoseidonCircuit 35 | #[allow(dead_code)] 36 | impl> PoseidonCircuit { 37 | pub fn new(a: F, b: F, c: F, hasher: HG::Native) -> Self { 38 | Self { a, b, c, hasher } 39 | } 40 | } 41 | 42 | impl> Clone for PoseidonCircuit { 43 | fn clone(&self) -> Self { 44 | PoseidonCircuit { 45 | a: self.a, 46 | b: self.b, 47 | c: self.c, 48 | hasher: self.hasher.clone(), 49 | } 50 | } 51 | } 52 | 53 | /// Implementation of the `ConstraintSynthesizer` trait for the 54 | /// `PoseidonCircuit` https://github.com/arkworks-rs/snark/blob/master/relations/src/r1cs/constraint_system.rs 55 | /// 56 | /// This is the main function that is called by the `R1CS` library to generate 57 | /// the constraints for the `PoseidonCircuit`. 58 | impl> ConstraintSynthesizer for PoseidonCircuit { 59 | fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { 60 | let a = FpVar::new_witness(cs.clone(), || Ok(self.a))?; 61 | let b = FpVar::new_witness(cs.clone(), || Ok(self.b))?; 62 | let res_target = FpVar::::new_input(cs.clone(), || Ok(&self.c))?; 63 | let hasher_gadget: HG = FieldHasherGadget::::from_native(&mut cs.clone(), self.hasher)?; 64 | 65 | let res_var = hasher_gadget.hash(&[a, b])?; 66 | 67 | res_var.enforce_equal(&res_target)?; 68 | 69 | Ok(()) 70 | } 71 | } 72 | 73 | #[cfg(test)] 74 | mod test { 75 | use super::*; 76 | use ark_bls12_381::{Bls12_381, Fr as BlsFr}; 77 | use ark_crypto_primitives::SNARK; 78 | use ark_groth16::Groth16; 79 | use ark_marlin::Marlin; 80 | use ark_poly::univariate::DensePolynomial; 81 | use ark_poly_commit::marlin_pc::MarlinKZG10; 82 | use ark_std::UniformRand; 83 | use arkworks_native_gadgets::poseidon::{ 84 | sbox::PoseidonSbox, FieldHasher, Poseidon, PoseidonParameters, 85 | }; 86 | use arkworks_r1cs_gadgets::poseidon::PoseidonGadget; 87 | use arkworks_utils::{ 88 | bytes_matrix_to_f, bytes_vec_to_f, poseidon_params::setup_poseidon_params, Curve, 89 | }; 90 | use blake2::Blake2s; 91 | type PoseidonC = PoseidonCircuit>; 92 | 93 | pub fn setup_params(curve: Curve, exp: i8, width: u8) -> PoseidonParameters { 94 | let pos_data = setup_poseidon_params(curve, exp, width).unwrap(); 95 | 96 | let mds_f = bytes_matrix_to_f(&pos_data.mds); 97 | let rounds_f = bytes_vec_to_f(&pos_data.rounds); 98 | 99 | let pos = PoseidonParameters { 100 | mds_matrix: mds_f, 101 | round_keys: rounds_f, 102 | full_rounds: pos_data.full_rounds, 103 | partial_rounds: pos_data.partial_rounds, 104 | sbox: PoseidonSbox(pos_data.exp), 105 | width: pos_data.width, 106 | }; 107 | 108 | pos 109 | } 110 | 111 | #[test] 112 | fn should_verify_poseidon_circuit() { 113 | let rng = &mut ark_std::test_rng(); 114 | let curve = Curve::Bls381; 115 | 116 | let a = BlsFr::rand(rng); 117 | let b = BlsFr::rand(rng); 118 | let parameters = setup_params(curve, 5, 3); 119 | let hasher = Poseidon::::new(parameters); 120 | 121 | let c = hasher.hash(&[a, b]).unwrap(); 122 | let nc = 3000; 123 | let nv = 2; 124 | let circuit = PoseidonC::new(a, b, c, hasher); 125 | 126 | type KZG10 = MarlinKZG10>; 127 | type MarlinSetup = Marlin; 128 | 129 | let srs = MarlinSetup::universal_setup(nc, nv, nv, rng).unwrap(); 130 | let (pk, vk) = MarlinSetup::index(&srs, circuit.clone()).unwrap(); 131 | let proof = MarlinSetup::prove(&pk, circuit, rng).unwrap(); 132 | 133 | let res = MarlinSetup::verify(&vk, &vec![c], &proof, rng).unwrap(); 134 | assert!(res); 135 | } 136 | 137 | #[test] 138 | fn should_verify_poseidon_circuit_groth16() { 139 | let rng = &mut ark_std::test_rng(); 140 | let curve = Curve::Bls381; 141 | 142 | let a = BlsFr::rand(rng); 143 | let b = BlsFr::rand(rng); 144 | let parameters = setup_params(curve, 5, 3); 145 | let hasher = Poseidon::::new(parameters); 146 | let c = hasher.hash(&[a, b]).unwrap(); 147 | let circuit = PoseidonC::new(a, b, c, hasher); 148 | 149 | type GrothSetup = Groth16; 150 | 151 | let (pk, vk) = GrothSetup::circuit_specific_setup(circuit.clone(), rng).unwrap(); 152 | let proof = GrothSetup::prove(&pk, circuit, rng).unwrap(); 153 | 154 | let res = GrothSetup::verify(&vk, &vec![c], &proof).unwrap(); 155 | assert!(res); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /arkworks-r1cs-circuits/src/vanchor.rs: -------------------------------------------------------------------------------- 1 | // This file is part of Webb. 2 | 3 | // Copyright (C) 2021 Webb Technologies Inc. 4 | // SPDX-License-Identifier: Apache-2.0 5 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); 7 | // you may not use this file except in compliance with the License. 8 | // You may obtain a copy of the License at 9 | // 10 | // http://www.apache.org/licenses/LICENSE-2.0 11 | // 12 | // Unless required by applicable law or agreed to in writing, software 13 | // distributed under the License is distributed on an "AS IS" BASIS, 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | // See the License for the specific language governing permissions and 16 | // limitations under the License. 17 | 18 | use ark_ff::fields::PrimeField; 19 | use ark_r1cs_std::{eq::EqGadget, fields::fp::FpVar, prelude::*}; 20 | use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}; 21 | use ark_std::vec::Vec; 22 | use arkworks_native_gadgets::merkle_tree::Path; 23 | use arkworks_r1cs_gadgets::{merkle_tree::PathVar, poseidon::FieldHasherGadget, set::SetGadget}; 24 | use core::cmp::Ordering::Less; 25 | 26 | /// Defines a VAnchorCircuit struct that hold all the information thats needed 27 | /// to verify the following statements: 28 | /// * Alice knows a witness tuple `(in_amounts, in_blindings, in_private_keys, 29 | /// in_path_elements, in_path_indices)` and a commitment_hash `Hash(chain_id, 30 | /// amount, pub_key, blinding)` stored in one of the valid VAnchor merkle 31 | /// trees 32 | /// * The VAnchor contract hasn't seen this nullifier_hash before. 33 | /// 34 | /// Needs to implement ConstraintSynthesizer and a 35 | /// constructor to generate proper constraints 36 | #[derive(Clone)] 37 | pub struct VAnchorCircuit< 38 | F: PrimeField, 39 | HG: FieldHasherGadget, 40 | const HEIGHT: usize, 41 | const N_INS: usize, 42 | const N_OUTS: usize, 43 | const ANCHOR_CT: usize, 44 | > { 45 | public_amount: F, 46 | ext_data_hash: F, 47 | 48 | in_amounts: Vec, 49 | in_blindings: Vec, 50 | in_private_keys: Vec, 51 | in_chain_id: F, 52 | root_set: [F; ANCHOR_CT], 53 | 54 | paths: Vec>, 55 | indices: Vec, 56 | nullifier_hash: Vec, 57 | 58 | out_commitment: Vec, 59 | out_amounts: Vec, 60 | out_blindings: Vec, 61 | out_chain_ids: Vec, 62 | out_pubkey: Vec, 63 | 64 | tree_hasher: HG::Native, 65 | keypair_hasher: HG::Native, 66 | leaf_hasher: HG::Native, 67 | nullifier_hasher: HG::Native, 68 | } 69 | 70 | /// Constructor for VAnchorCircuit 71 | impl< 72 | F, 73 | HG, 74 | const HEIGHT: usize, 75 | const N_INS: usize, 76 | const N_OUTS: usize, 77 | const ANCHOR_CT: usize, 78 | > VAnchorCircuit 79 | where 80 | F: PrimeField, 81 | HG: FieldHasherGadget, 82 | { 83 | #[allow(clippy::too_many_arguments)] 84 | pub fn new( 85 | public_amount: F, 86 | ext_data_hash: F, 87 | in_amounts: Vec, 88 | in_blindings: Vec, 89 | in_private_keys: Vec, 90 | in_chain_id: F, 91 | root_set: [F; ANCHOR_CT], 92 | paths: Vec>, 93 | indices: Vec, 94 | nullifier_hash: Vec, 95 | out_commitment: Vec, 96 | out_amounts: Vec, 97 | out_blindings: Vec, 98 | out_chain_ids: Vec, 99 | out_pubkey: Vec, 100 | tree_hasher: HG::Native, 101 | keypair_hasher: HG::Native, 102 | leaf_hasher: HG::Native, 103 | nullifier_hasher: HG::Native, 104 | ) -> Self { 105 | Self { 106 | public_amount, 107 | ext_data_hash, 108 | in_amounts, 109 | in_blindings, 110 | in_private_keys, 111 | in_chain_id, 112 | root_set, 113 | paths, 114 | indices, 115 | nullifier_hash, 116 | out_commitment, 117 | out_amounts, 118 | out_blindings, 119 | out_chain_ids, 120 | out_pubkey, 121 | tree_hasher, 122 | keypair_hasher, 123 | leaf_hasher, 124 | nullifier_hasher, 125 | } 126 | } 127 | 128 | // Check that there are no same nullifiers among all inputs 129 | pub fn verify_no_same_nul(in_nullifier_var: &[FpVar]) -> Result<(), SynthesisError> { 130 | for i in 0..N_INS - 1 { 131 | for j in (i + 1)..N_INS { 132 | in_nullifier_var[i].enforce_not_equal(&in_nullifier_var[j])?; 133 | } 134 | } 135 | 136 | Ok(()) 137 | } 138 | 139 | // Verify amount invariant 140 | pub fn verify_input_invariant( 141 | public_amount_var: &FpVar, 142 | sum_ins_var: &FpVar, 143 | sum_outs_var: &FpVar, 144 | ) -> Result<(), SynthesisError> { 145 | let res = sum_ins_var + public_amount_var; 146 | res.enforce_equal(sum_outs_var)?; 147 | Ok(()) 148 | } 149 | } 150 | 151 | impl< 152 | F, 153 | HG, 154 | const HEIGHT: usize, 155 | const N_INS: usize, 156 | const N_OUTS: usize, 157 | const ANCHOR_CT: usize, 158 | > ConstraintSynthesizer for VAnchorCircuit 159 | where 160 | F: PrimeField, 161 | HG: FieldHasherGadget, 162 | { 163 | fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { 164 | let public_amount = self.public_amount; 165 | let ext_data_hash = self.ext_data_hash; 166 | let in_amounts = self.in_amounts; 167 | let in_blindings = self.in_blindings; 168 | let in_chain_id = self.in_chain_id; 169 | let in_private_keys = self.in_private_keys; 170 | let out_chain_ids = self.out_chain_ids; 171 | let root_set = self.root_set; 172 | let paths = self.paths; 173 | let indices = self.indices; 174 | let nullifier_hash = self.nullifier_hash; 175 | 176 | let out_commitment = self.out_commitment; 177 | let out_amounts = self.out_amounts; 178 | let out_blindings = self.out_blindings; 179 | let out_pubkey = self.out_pubkey; 180 | 181 | // 2^248 182 | let limit: F = F::from_str( 183 | "452312848583266388373324160190187140051835877600158453279131187530910662656", 184 | ) 185 | .unwrap_or_default(); 186 | // check the previous conversion is done correctly 187 | assert_ne!(limit, F::default()); 188 | // Generating vars 189 | // Public inputs 190 | let public_amount_var = FpVar::::new_input(cs.clone(), || Ok(public_amount))?; 191 | let arbitrary_input_var = FpVar::::new_input(cs.clone(), || Ok(ext_data_hash))?; 192 | let in_nullifier_var = Vec::>::new_input(cs.clone(), || Ok(nullifier_hash))?; 193 | let out_commitment_var = Vec::>::new_input(cs.clone(), || Ok(out_commitment))?; 194 | let in_chain_id_var = FpVar::::new_input(cs.clone(), || Ok(in_chain_id))?; 195 | let root_set_var = Vec::>::new_input(cs.clone(), || Ok(root_set))?; 196 | 197 | // Constants 198 | let limit_var: FpVar = FpVar::::new_constant(cs.clone(), limit)?; 199 | 200 | // Hashers 201 | let tree_hasher = HG::from_native(&mut cs.clone(), self.tree_hasher)?; 202 | let keypair_hasher = HG::from_native(&mut cs.clone(), self.keypair_hasher)?; 203 | let leaf_hasher = HG::from_native(&mut cs.clone(), self.leaf_hasher)?; 204 | let nullifier_hasher = HG::from_native(&mut cs.clone(), self.nullifier_hasher)?; 205 | 206 | // Private inputs 207 | let in_amounts_var = Vec::>::new_witness(cs.clone(), || Ok(in_amounts))?; 208 | let in_blindings_var = Vec::>::new_witness(cs.clone(), || Ok(in_blindings))?; 209 | let in_private_keys_var = Vec::>::new_witness(cs.clone(), || Ok(in_private_keys))?; 210 | let in_path_elements_var = 211 | Vec::>::new_witness(cs.clone(), || Ok(paths))?; 212 | let in_path_indices_var = Vec::>::new_witness(cs.clone(), || Ok(indices))?; 213 | 214 | // Outputs 215 | let out_amounts_var = Vec::>::new_witness(cs.clone(), || Ok(out_amounts))?; 216 | let out_blindings_var = Vec::>::new_witness(cs.clone(), || Ok(out_blindings))?; 217 | let out_chain_ids_var = Vec::>::new_witness(cs.clone(), || Ok(out_chain_ids))?; 218 | let out_pubkey_var = Vec::>::new_witness(cs, || Ok(out_pubkey))?; 219 | 220 | let set_gadget = SetGadget::new(root_set_var); 221 | 222 | // verify correctness of transaction inputs 223 | let mut sum_ins_var = FpVar::::zero(); 224 | for tx in 0..N_INS { 225 | // Computing the public key 226 | let pub_key = keypair_hasher.hash(&[in_private_keys_var[tx].clone()])?; 227 | // Computing the hash 228 | let in_leaf = leaf_hasher.hash(&[ 229 | in_chain_id_var.clone(), 230 | in_amounts_var[tx].clone(), 231 | pub_key, 232 | in_blindings_var[tx].clone(), 233 | ])?; 234 | // End of computing the hash 235 | 236 | let signature = nullifier_hasher.hash(&[ 237 | in_private_keys_var[tx].clone(), 238 | in_leaf.clone(), 239 | in_path_indices_var[tx].clone(), 240 | ])?; 241 | // Nullifier 242 | let nullifier_hash = nullifier_hasher.hash(&[ 243 | in_leaf.clone(), 244 | in_path_indices_var[tx].clone(), 245 | signature, 246 | ])?; 247 | 248 | nullifier_hash.enforce_equal(&in_nullifier_var[tx])?; 249 | 250 | // Add the roots and diffs signals to the vanchor circuit 251 | let roothash = &in_path_elements_var[tx].root_hash(&in_leaf, &tree_hasher)?; 252 | let in_amount_tx = &in_amounts_var[tx]; 253 | 254 | // Check membership if in_amount is non zero 255 | let check = set_gadget.check_membership_enabled(&roothash, in_amount_tx)?; 256 | check.enforce_equal(&Boolean::TRUE)?; 257 | 258 | sum_ins_var += in_amount_tx; 259 | } 260 | // verify correctness of transaction outputs 261 | let mut sum_outs_var = FpVar::::zero(); 262 | for tx in 0..N_OUTS { 263 | // Computing the hash 264 | let leaf = leaf_hasher.hash(&[ 265 | out_chain_ids_var[tx].clone(), 266 | out_amounts_var[tx].clone(), 267 | out_pubkey_var[tx].clone(), 268 | out_blindings_var[tx].clone(), 269 | ])?; 270 | // End of computing the hash 271 | let out_amount_var = &out_amounts_var[tx]; 272 | leaf.enforce_equal(&out_commitment_var[tx])?; 273 | 274 | // Check that amount is less than 2^248 in the field (to prevent overflow) 275 | out_amount_var.enforce_cmp_unchecked(&limit_var, Less, false)?; 276 | 277 | sum_outs_var += out_amount_var; 278 | } 279 | 280 | // check that there are no same nullifiers among all inputs 281 | Self::verify_no_same_nul(&in_nullifier_var)?; 282 | 283 | // verify amount invariant 284 | Self::verify_input_invariant(&public_amount_var, &sum_ins_var, &sum_outs_var)?; 285 | 286 | // optional safety constraint to make sure extDataHash cannot be changed 287 | let _ = &arbitrary_input_var * &arbitrary_input_var; 288 | 289 | Ok(()) 290 | } 291 | } 292 | -------------------------------------------------------------------------------- /arkworks-r1cs-gadgets/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /arkworks-r1cs-gadgets/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "arkworks-r1cs-gadgets" 3 | version = "1.0.0" 4 | authors = ["Webb Developers"] 5 | edition = "2018" 6 | description = "Webb protocol's r1cs zero-knowledge gadgets written using Arkworks" 7 | license = "Apache-2.0" 8 | repository = "https://github.com/webb-tools/arkworks-gadgets" 9 | homepage = "https://webb.tools" 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | arkworks-native-gadgets = { path = "../arkworks-native-gadgets", version = "1.0.0", default-features = false } 15 | 16 | ark-crypto-primitives = { version = "^0.3.0", features = ["r1cs"], default-features = false } 17 | ark-ff = { version = "^0.3.0", default-features = false } 18 | ark-std = { version = "^0.3.0", default-features = false } 19 | ark-r1cs-std = { version = "^0.3.0", default-features = false } 20 | ark-relations = { version = "^0.3.0", default-features = false } 21 | 22 | [dev-dependencies] 23 | ark-marlin = { version = "^0.3.0", default-features = false } 24 | ark-groth16 = { version = "^0.3.0", default-features = false } 25 | blake2 = { version = "0.9", default-features = false } 26 | ark-poly-commit = { version = "^0.3.0", default-features = false } 27 | ark-poly = { version = "^0.3.0", default-features = false } 28 | ark-snark = { version = "^0.3.0", default-features = false } 29 | ark-ec = { version = "^0.3.0", default-features = false } 30 | ark-serialize = {version = "^0.3.0", default-features = false } 31 | digest = { version = "0.9" } 32 | crypto_box = { version = "0.7.1" } 33 | 34 | # curves 35 | ark-ed-on-bn254 = { version = "^0.3.0", default-features = false, features = [ "r1cs" ] } 36 | ark-bls12-381 = { version = "^0.3.0", default-features = false, features = [ "curve" ] } 37 | 38 | [dev-dependencies.arkworks-utils] 39 | path = "../arkworks-utils" 40 | default-features = false 41 | features = ["poseidon_bn254_x5_3", "mimc_ed_on_bn254_220"] 42 | 43 | [features] 44 | default = ["std"] 45 | std = [ 46 | "ark-std/std", 47 | "arkworks-native-gadgets/std", 48 | "ark-ff/std", 49 | "ark-std/std", 50 | "ark-r1cs-std/std", 51 | "ark-relations/std" 52 | ] 53 | parallel = [ 54 | "ark-crypto-primitives/parallel", 55 | "arkworks-native-gadgets/parallel", 56 | "ark-ff/parallel", 57 | "ark-std/parallel", 58 | "ark-r1cs-std/parallel", 59 | ] 60 | -------------------------------------------------------------------------------- /arkworks-r1cs-gadgets/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | 3 | #[macro_use] 4 | pub extern crate ark_std; 5 | 6 | use ark_std::boxed::Box; 7 | pub(crate) use ark_std::vec::Vec; 8 | 9 | pub mod merkle_tree; 10 | pub mod mimc; 11 | pub mod poseidon; 12 | pub mod set; 13 | 14 | use ark_ff::{BigInteger, PrimeField}; 15 | use ark_r1cs_std::{fields::fp::FpVar, prelude::*, uint8::UInt8}; 16 | use ark_relations::r1cs::SynthesisError; 17 | 18 | /// Converts bytearray to `Vec>` 19 | pub fn to_field_var_elements( 20 | bytes: &[UInt8], 21 | ) -> Result>, SynthesisError> { 22 | let max_size = F::BigInt::NUM_LIMBS * 8; 23 | 24 | // Pad the input with zeros 25 | let padding_len = (max_size - (bytes.len() % max_size)) % max_size; 26 | let padded_input: Vec> = bytes 27 | .iter() 28 | .cloned() 29 | .chain(core::iter::repeat(UInt8::constant(0u8)).take(padding_len)) 30 | .collect(); 31 | 32 | let res = padded_input 33 | .chunks(max_size) 34 | .map(|chunk| Boolean::le_bits_to_fp_var(chunk.to_bits_le()?.as_slice())) 35 | .collect::, SynthesisError>>()?; 36 | 37 | Ok(res) 38 | } 39 | -------------------------------------------------------------------------------- /arkworks-r1cs-gadgets/src/mimc.rs: -------------------------------------------------------------------------------- 1 | use super::to_field_var_elements; 2 | use ark_crypto_primitives::crh::constraints::{CRHGadget as CRHGadgetTrait, TwoToOneCRHGadget}; 3 | use ark_ff::PrimeField; 4 | use ark_r1cs_std::{ 5 | alloc::AllocVar, 6 | fields::{fp::FpVar, FieldVar}, 7 | prelude::*, 8 | uint8::UInt8, 9 | }; 10 | use ark_relations::r1cs::{Namespace, SynthesisError}; 11 | use ark_std::{marker::PhantomData, vec::Vec}; 12 | use arkworks_native_gadgets::mimc::{MiMCParameters, Rounds, CRH}; 13 | use core::borrow::Borrow; 14 | 15 | #[derive(Clone)] 16 | pub struct MiMCParametersVar { 17 | pub k: FpVar, 18 | pub rounds: usize, 19 | pub num_inputs: usize, 20 | pub num_outputs: usize, 21 | pub round_keys: Vec>, 22 | } 23 | 24 | impl Default for MiMCParametersVar { 25 | fn default() -> Self { 26 | Self { 27 | k: FpVar::::zero(), 28 | rounds: usize::default(), 29 | num_inputs: usize::default(), 30 | num_outputs: usize::default(), 31 | round_keys: Vec::default(), 32 | } 33 | } 34 | } 35 | 36 | pub struct CRHGadget { 37 | field: PhantomData, 38 | params: PhantomData

, 39 | } 40 | 41 | impl CRHGadget { 42 | fn mimc( 43 | parameters: &MiMCParametersVar, 44 | state: Vec>, 45 | ) -> Result>, SynthesisError> { 46 | assert!(state.len() == parameters.num_inputs); 47 | let mut l_out: FpVar = FpVar::::zero(); 48 | let mut r_out: FpVar = FpVar::::zero(); 49 | 50 | for (i, s) in state.iter().enumerate() { 51 | let l: FpVar; 52 | let r: FpVar; 53 | if i == 0 { 54 | l = s.clone(); 55 | r = FpVar::::zero(); 56 | } else { 57 | l = l_out.clone() + s.clone(); 58 | r = r_out.clone(); 59 | } 60 | 61 | let res = Self::feistel(parameters, l, r)?; 62 | l_out = res[0].clone(); 63 | r_out = res[1].clone(); 64 | } 65 | 66 | let mut outs = vec![l_out.clone()]; 67 | for _ in 0..parameters.num_outputs { 68 | let res = Self::feistel(parameters, l_out.clone(), r_out.clone())?; 69 | l_out = res[0].clone(); 70 | r_out = res[1].clone(); 71 | outs.push(l_out.clone()); 72 | } 73 | 74 | Ok(outs) 75 | } 76 | 77 | fn feistel( 78 | parameters: &MiMCParametersVar, 79 | left: FpVar, 80 | right: FpVar, 81 | ) -> Result<[FpVar; 2], SynthesisError> { 82 | let mut x_l = left; 83 | let mut x_r = right; 84 | let mut c: FpVar; 85 | let mut t: FpVar; 86 | let mut t2: FpVar; 87 | let mut t4: FpVar; 88 | for i in 0..parameters.rounds { 89 | c = if i == 0 || i == parameters.rounds - 1 { 90 | FpVar::::zero() 91 | } else { 92 | parameters.round_keys[i - 1].clone() 93 | }; 94 | t = if i == 0 { 95 | parameters.k.clone() + x_l.clone() 96 | } else { 97 | parameters.k.clone() + x_l.clone() + c 98 | }; 99 | 100 | t2 = t.clone() * t.clone(); 101 | t4 = t2.clone() * t2.clone(); 102 | 103 | let temp_x_l = x_l.clone(); 104 | let temp_x_r = x_r.clone(); 105 | 106 | if i < parameters.rounds - 1 { 107 | x_l = if i == 0 { temp_x_r } else { temp_x_r + t4 * t }; 108 | 109 | x_r = temp_x_l; 110 | } else { 111 | x_r = temp_x_r + t4 * t; 112 | x_l = temp_x_l; 113 | } 114 | } 115 | 116 | Ok([x_l, x_r]) 117 | } 118 | } 119 | 120 | // https://github.com/arkworks-rs/r1cs-std/blob/master/src/bits/uint8.rs#L343 121 | impl CRHGadgetTrait, F> for CRHGadget { 122 | type OutputVar = FpVar; 123 | type ParametersVar = MiMCParametersVar; 124 | 125 | fn evaluate( 126 | parameters: &Self::ParametersVar, 127 | input: &[UInt8], 128 | ) -> Result { 129 | let f_var_inputs: Vec> = to_field_var_elements(input)?; 130 | if f_var_inputs.len() > P::WIDTH as usize { 131 | panic!( 132 | "incorrect input length {:?} for width {:?}", 133 | f_var_inputs.len(), 134 | P::WIDTH, 135 | ); 136 | } 137 | 138 | let mut buffer = vec![FpVar::zero(); P::WIDTH as usize]; 139 | buffer 140 | .iter_mut() 141 | .zip(f_var_inputs) 142 | .for_each(|(b, l_b)| *b = l_b); 143 | 144 | let result = Self::mimc(parameters, buffer); 145 | result.map(|x| x.get(0).cloned().ok_or(SynthesisError::AssignmentMissing))? 146 | } 147 | } 148 | 149 | impl TwoToOneCRHGadget, F> for CRHGadget { 150 | type OutputVar = FpVar; 151 | type ParametersVar = MiMCParametersVar; 152 | 153 | fn evaluate( 154 | parameters: &Self::ParametersVar, 155 | left_input: &[UInt8], 156 | right_input: &[UInt8], 157 | ) -> Result { 158 | // assume equality of left and right length 159 | assert_eq!(left_input.len(), right_input.len()); 160 | let chained_input: Vec<_> = left_input 161 | .to_vec() 162 | .into_iter() 163 | .chain(right_input.to_vec().into_iter()) 164 | .collect(); 165 | >::evaluate(parameters, &chained_input) 166 | } 167 | } 168 | 169 | impl AllocVar, F> for MiMCParametersVar { 170 | fn new_variable>>( 171 | _cs: impl Into>, 172 | f: impl FnOnce() -> Result, 173 | _mode: AllocationMode, 174 | ) -> Result { 175 | let params = f()?.borrow().clone(); 176 | 177 | let mut round_keys_var = Vec::new(); 178 | for rk in params.round_keys { 179 | round_keys_var.push(FpVar::Constant(rk)); 180 | } 181 | 182 | Ok(Self { 183 | round_keys: round_keys_var, 184 | k: FpVar::Constant(params.k), 185 | rounds: params.rounds, 186 | num_inputs: params.num_inputs, 187 | num_outputs: params.num_outputs, 188 | }) 189 | } 190 | } 191 | 192 | #[cfg(test)] 193 | mod test { 194 | #![allow(non_camel_case_types)] 195 | 196 | use super::*; 197 | use ark_crypto_primitives::crh::CRH as CRHTrait; 198 | use ark_ed_on_bn254::Fq; 199 | use ark_ff::{to_bytes, Zero}; 200 | use ark_relations::r1cs::ConstraintSystem; 201 | use arkworks_utils::{bytes_vec_to_f, mimc_params::setup_mimc_params, Curve}; 202 | 203 | #[derive(Default, Clone)] 204 | struct MiMCRounds220_2; 205 | 206 | impl Rounds for MiMCRounds220_2 { 207 | const ROUNDS: u16 = 220; 208 | const WIDTH: u8 = 2; 209 | } 210 | 211 | type MiMC220_2 = CRH; 212 | type MiMC220Gadget_2 = CRHGadget; 213 | 214 | #[derive(Default, Clone)] 215 | struct MiMCRounds220_3; 216 | 217 | impl Rounds for MiMCRounds220_3 { 218 | const ROUNDS: u16 = 220; 219 | const WIDTH: u8 = 3; 220 | } 221 | 222 | type MiMC220_3 = CRH; 223 | type MiMC220Gadget_3 = CRHGadget; 224 | 225 | pub fn setup_mimc(curve: Curve, rounds: u16, width: u8) -> MiMCParameters { 226 | let mimc_data = setup_mimc_params(curve, rounds, width).unwrap(); 227 | let constants_f = bytes_vec_to_f(&mimc_data.constants); 228 | 229 | let mimc_p = MiMCParameters { 230 | k: F::zero(), 231 | num_inputs: mimc_data.width as usize, 232 | num_outputs: mimc_data.width as usize, 233 | rounds: mimc_data.rounds as usize, 234 | round_keys: constants_f, 235 | }; 236 | 237 | mimc_p 238 | } 239 | 240 | #[test] 241 | fn test_mimc_native_equality() { 242 | let curve = Curve::Bn254; 243 | let cs = ConstraintSystem::::new_ref(); 244 | 245 | let params = setup_mimc(curve, MiMCRounds220_3::ROUNDS, MiMCRounds220_3::WIDTH); 246 | 247 | let params_var = 248 | MiMCParametersVar::new_variable(cs.clone(), || Ok(¶ms), AllocationMode::Constant) 249 | .unwrap(); 250 | 251 | // Test MiMC on an input of 3 field elements. 252 | let aligned_inp = to_bytes![Fq::zero(), Fq::from(1u128), Fq::from(2u128)].unwrap(); 253 | let aligned_inp_var = 254 | Vec::>::new_input(cs.clone(), || Ok(aligned_inp.clone())).unwrap(); 255 | 256 | let res = MiMC220_3::evaluate(¶ms, &aligned_inp).unwrap(); 257 | let res_var = >::evaluate( 258 | ¶ms_var.clone(), 259 | &aligned_inp_var, 260 | ) 261 | .unwrap(); 262 | assert_eq!(res, res_var.value().unwrap()); 263 | } 264 | } 265 | -------------------------------------------------------------------------------- /arkworks-r1cs-gadgets/src/poseidon/mod.rs: -------------------------------------------------------------------------------- 1 | //! A R1CS contraint generation implementation of the Poseidon hash function. 2 | //! 3 | //! For a more through description for poseidon hash refer to 4 | //! [arkworks_native_gadgets::poseidon] 5 | 6 | ///Importing dependencies 7 | use ark_ff::PrimeField; 8 | use ark_r1cs_std::{ 9 | alloc::AllocVar, 10 | fields::{fp::FpVar, FieldVar}, 11 | prelude::*, 12 | }; 13 | use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; 14 | use ark_std::{fmt::Debug, vec::Vec}; 15 | use arkworks_native_gadgets::poseidon::{ 16 | sbox::PoseidonSbox, FieldHasher, Poseidon, PoseidonParameters, 17 | }; 18 | 19 | use core::{ 20 | borrow::Borrow, 21 | ops::{Add, AddAssign, Mul}, 22 | }; 23 | 24 | pub mod sbox; 25 | use sbox::SboxConstraints; 26 | 27 | /// FieldHasher gadget for `PrimeFields` 28 | pub trait FieldHasherGadget 29 | where 30 | Self: Sized, 31 | { 32 | type Native: Debug + Clone + FieldHasher; 33 | 34 | // For easy conversion from native version 35 | fn from_native( 36 | cs: &mut ConstraintSystemRef, 37 | native: Self::Native, 38 | ) -> Result; 39 | fn hash(&self, inputs: &[FpVar]) -> Result, SynthesisError>; 40 | fn hash_two(&self, left: &FpVar, right: &FpVar) -> Result, SynthesisError>; 41 | } 42 | 43 | /// Parameters for poseidon hash 44 | #[derive(Default, Clone)] 45 | pub struct PoseidonParametersVar { 46 | /// The round key constants 47 | pub round_keys: Vec>, 48 | /// The MDS matrix to apply in the mix layer. 49 | pub mds_matrix: Vec>>, 50 | /// Number of full SBox rounds 51 | pub full_rounds: u8, 52 | /// Number of partial rounds 53 | pub partial_rounds: u8, 54 | /// The size of the permutation, in field elements. 55 | pub width: u8, 56 | /// The S-box to apply in the sub words layer. 57 | pub sbox: PoseidonSbox, 58 | } 59 | 60 | impl AllocVar, F> for PoseidonParametersVar { 61 | fn new_variable>>( 62 | cs: impl Into>, 63 | f: impl FnOnce() -> Result, 64 | mode: AllocationMode, 65 | ) -> Result { 66 | let params = f()?.borrow().clone(); 67 | let mut round_keys_var = Vec::new(); 68 | let ns = cs.into(); 69 | let cs = ns.cs(); 70 | for rk in params.round_keys { 71 | round_keys_var.push(FpVar::::new_variable(cs.clone(), || Ok(rk), mode)?); 72 | } 73 | let mut mds_var = Vec::new(); 74 | for row in params.mds_matrix { 75 | let mut row_var = Vec::new(); 76 | for mk in row { 77 | row_var.push(FpVar::::new_variable(cs.clone(), || Ok(mk), mode)?); 78 | } 79 | mds_var.push(row_var); 80 | } 81 | let full_rounds = params.full_rounds; 82 | let partial_rounds = params.partial_rounds; 83 | let width = params.width; 84 | let sbox = params.sbox; 85 | 86 | Ok(Self { 87 | round_keys: round_keys_var, 88 | mds_matrix: mds_var, 89 | full_rounds, 90 | partial_rounds, 91 | width, 92 | sbox, 93 | }) 94 | } 95 | } 96 | 97 | #[derive(Default, Clone)] 98 | pub struct PoseidonGadget { 99 | pub params: PoseidonParametersVar, 100 | } 101 | 102 | impl PoseidonGadget { 103 | /// Calculates poseidon permutations of state wrt `PoseidonParametersVar` 104 | pub fn permute(&self, mut state: Vec>) -> Result>, SynthesisError> { 105 | let params = &self.params; 106 | let nr = (params.full_rounds + params.partial_rounds) as usize; 107 | for r in 0..nr { 108 | state.iter_mut().enumerate().for_each(|(i, a)| { 109 | let c = ¶ms.round_keys[(r * (params.width as usize) + i)]; 110 | a.add_assign(c); 111 | }); 112 | 113 | let half_rounds = (params.full_rounds as usize) / 2; 114 | if r < half_rounds || r >= half_rounds + (params.partial_rounds as usize) { 115 | state 116 | .iter_mut() 117 | .try_for_each(|a| params.sbox.synthesize_sbox(a).map(|f| *a = f))?; 118 | } else { 119 | state[0] = params.sbox.synthesize_sbox(&state[0])?; 120 | } 121 | 122 | state = state 123 | .iter() 124 | .enumerate() 125 | .map(|(i, _)| { 126 | state 127 | .iter() 128 | .enumerate() 129 | .fold(FpVar::::zero(), |acc, (j, a)| { 130 | let m = ¶ms.mds_matrix[i][j]; 131 | acc.add(m.mul(a)) 132 | }) 133 | }) 134 | .collect(); 135 | } 136 | Ok(state) 137 | } 138 | } 139 | 140 | impl FieldHasherGadget for PoseidonGadget { 141 | type Native = Poseidon; 142 | 143 | fn from_native( 144 | cs: &mut ConstraintSystemRef, 145 | native: Self::Native, 146 | ) -> Result { 147 | let params = PoseidonParametersVar::new_variable( 148 | cs.clone(), 149 | || Ok(native.params), 150 | AllocationMode::Constant, 151 | )?; 152 | Ok(Self { params }) 153 | } 154 | 155 | /// Calculates poseidon hash of inputs wrt `PoseidonParametersVar` 156 | fn hash(&self, inputs: &[FpVar]) -> Result, SynthesisError> { 157 | let parameters = &self.params; 158 | if inputs.len() >= parameters.width.into() { 159 | panic!( 160 | "incorrect input length {:?} for width {:?} -- input bits {:?}", 161 | inputs.len(), 162 | parameters.width, 163 | inputs.len() 164 | ); 165 | } 166 | 167 | let mut buffer = vec![FpVar::zero(); parameters.width as usize]; 168 | buffer 169 | .iter_mut() 170 | .skip(1) 171 | .zip(inputs) 172 | .for_each(|(a, b)| *a = b.clone()); 173 | let result = self.permute(buffer); 174 | result.map(|x| x.get(0).cloned().ok_or(SynthesisError::AssignmentMissing))? 175 | } 176 | 177 | /// utility function to hash to adjacent leaves together 178 | fn hash_two(&self, left: &FpVar, right: &FpVar) -> Result, SynthesisError> { 179 | self.hash(&[left.clone(), right.clone()]) 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /arkworks-r1cs-gadgets/src/poseidon/sbox.rs: -------------------------------------------------------------------------------- 1 | use super::PoseidonSbox; 2 | use ark_ff::PrimeField; 3 | use ark_r1cs_std::fields::{fp::FpVar, FieldVar}; 4 | use ark_relations::r1cs::SynthesisError; 5 | 6 | pub trait SboxConstraints { 7 | fn synthesize_sbox(&self, input: &FpVar) -> Result, SynthesisError>; 8 | } 9 | 10 | impl SboxConstraints for PoseidonSbox { 11 | fn synthesize_sbox( 12 | &self, 13 | input_var: &FpVar, 14 | ) -> Result, SynthesisError> { 15 | match self.0 { 16 | 3 => synthesize_exp3_sbox::(input_var), 17 | 5 => synthesize_exp5_sbox::(input_var), 18 | 17 => synthesize_exp17_sbox::(input_var), 19 | -1 => synthesize_inverse_sbox::(input_var), 20 | _ => synthesize_exp3_sbox::(input_var), 21 | } 22 | } 23 | } 24 | 25 | // Allocate variables in circuit and enforce constraints when Sbox as cube 26 | fn synthesize_exp3_sbox(input_var: &FpVar) -> Result, SynthesisError> { 27 | let sqr = input_var * input_var; 28 | let cube = input_var * sqr; 29 | Ok(cube) 30 | } 31 | 32 | // Allocate variables in circuit and enforce constraints when Sbox as cube 33 | fn synthesize_exp5_sbox(input_var: &FpVar) -> Result, SynthesisError> { 34 | let sqr = input_var * input_var; 35 | let fourth = &sqr * &sqr; 36 | let fifth = input_var * fourth; 37 | Ok(fifth) 38 | } 39 | 40 | // Allocate variables in circuit and enforce constraints when Sbox as cube 41 | fn synthesize_exp17_sbox(input_var: &FpVar) -> Result, SynthesisError> { 42 | let sqr = input_var * input_var; 43 | let fourth = &sqr * &sqr; 44 | let eigth = &fourth * &fourth; 45 | let sixteenth = &eigth * &eigth; 46 | let seventeenth = &sixteenth * input_var; 47 | Ok(seventeenth) 48 | } 49 | 50 | // Allocate variables in circuit and enforce constraints when Sbox as 51 | // inverse 52 | fn synthesize_inverse_sbox( 53 | input_var: &FpVar, 54 | ) -> Result, SynthesisError> { 55 | input_var.inverse() 56 | } 57 | -------------------------------------------------------------------------------- /arkworks-r1cs-gadgets/src/set.rs: -------------------------------------------------------------------------------- 1 | use crate::Vec; 2 | use ark_ff::fields::PrimeField; 3 | use ark_r1cs_std::{ 4 | eq::EqGadget, 5 | fields::{fp::FpVar, FieldVar}, 6 | prelude::*, 7 | }; 8 | use ark_relations::r1cs::SynthesisError; 9 | 10 | pub struct SetGadget { 11 | set: Vec>, 12 | } 13 | 14 | impl SetGadget { 15 | pub fn new(set: Vec>) -> Self { 16 | Self { set } 17 | } 18 | 19 | /// Calculates product between (set_element - target) for every set_element. 20 | /// Outputs 0 iff `set_element == target` for at least one element of the 21 | /// set. This is an utility function to prove membership of a merkle_root in 22 | /// a set of merkle_roots 23 | pub fn calculate_product>( 24 | &self, 25 | target: &T, 26 | ) -> Result, SynthesisError> { 27 | let target = Boolean::le_bits_to_fp_var(&target.to_bytes()?.to_bits_le()?)?; 28 | // Calculating the diffs inside the circuit 29 | let mut diffs = Vec::new(); 30 | for item in &self.set { 31 | diffs.push(item - &target); 32 | } 33 | 34 | // Checking the membership 35 | let mut product = 36 | FpVar::::new_variable(target.cs(), || Ok(F::one()), AllocationMode::Constant)?; 37 | for diff in diffs.iter() { 38 | product *= diff; 39 | } 40 | 41 | Ok(product) 42 | } 43 | 44 | /// Checks if target is present in the set 45 | pub fn check_membership>( 46 | &self, 47 | target: &T, 48 | ) -> Result, SynthesisError> { 49 | let product = self.calculate_product(target)?; 50 | 51 | product.is_eq(&FpVar::::zero()) 52 | } 53 | 54 | pub fn check_membership_enabled>( 55 | &self, 56 | target: &T, 57 | is_enabled: &FpVar, 58 | ) -> Result, SynthesisError> { 59 | let mut product = self.calculate_product(target)?; 60 | 61 | product *= is_enabled; 62 | product.is_eq(&FpVar::::zero()) 63 | } 64 | } 65 | 66 | #[cfg(test)] 67 | mod test { 68 | use super::*; 69 | use ark_bls12_381::Fr; 70 | use ark_relations::r1cs::ConstraintSystem; 71 | 72 | #[test] 73 | fn should_verify_set_membership() { 74 | let cs = ConstraintSystem::::new_ref(); 75 | 76 | let set = vec![Fr::from(1u32), Fr::from(2u32), Fr::from(3u32)]; 77 | let target = Fr::from(1u32); 78 | let target_var = FpVar::::new_input(cs.clone(), || Ok(target)).unwrap(); 79 | let set_var = Vec::>::new_input(cs.clone(), || Ok(set)).unwrap(); 80 | 81 | let set_gadget = SetGadget::new(set_var); 82 | let is_member = set_gadget.check_membership(&target_var).unwrap(); 83 | 84 | is_member.enforce_equal(&Boolean::TRUE).unwrap(); 85 | 86 | assert!(cs.is_satisfied().unwrap()); 87 | } 88 | 89 | #[test] 90 | fn should_not_verify_set_non_membership() { 91 | let cs = ConstraintSystem::::new_ref(); 92 | 93 | let set = vec![Fr::from(1u32), Fr::from(2u32), Fr::from(3u32)]; 94 | let target = Fr::from(4u32); 95 | let target_var = FpVar::::new_input(cs.clone(), || Ok(target)).unwrap(); 96 | let set_var = Vec::>::new_input(cs.clone(), || Ok(set)).unwrap(); 97 | 98 | let set_gadget = SetGadget::new(set_var); 99 | let is_member = set_gadget.check_membership(&target_var).unwrap(); 100 | 101 | is_member.enforce_equal(&Boolean::TRUE).unwrap(); 102 | 103 | assert!(!cs.is_satisfied().unwrap()); 104 | } 105 | 106 | #[test] 107 | fn should_verify_set_membership_if_enabled() { 108 | let cs = ConstraintSystem::::new_ref(); 109 | 110 | // enable == 1 == true 111 | let enabled = Fr::from(1u32); 112 | let set = vec![Fr::from(1u32), Fr::from(2u32), Fr::from(3u32)]; 113 | let target = Fr::from(1u32); 114 | 115 | let enabled_var = FpVar::::new_input(cs.clone(), || Ok(enabled)).unwrap(); 116 | let target_var = FpVar::::new_input(cs.clone(), || Ok(target)).unwrap(); 117 | let set_var = Vec::>::new_input(cs.clone(), || Ok(set)).unwrap(); 118 | 119 | let set_gadget = SetGadget::new(set_var); 120 | let is_member = set_gadget 121 | .check_membership_enabled(&target_var, &enabled_var) 122 | .unwrap(); 123 | 124 | is_member.enforce_equal(&Boolean::TRUE).unwrap(); 125 | 126 | assert!(cs.is_satisfied().unwrap()); 127 | } 128 | 129 | #[test] 130 | fn should_not_verify_non_set_membership_if_enabled() { 131 | let cs = ConstraintSystem::::new_ref(); 132 | 133 | // enable == 1 == true 134 | // Set gadget now functions normally, meaning it values that are not in the set 135 | // will yeald to false 136 | let enabled = Fr::from(1u32); 137 | let set = vec![Fr::from(1u32), Fr::from(2u32), Fr::from(3u32)]; 138 | let target = Fr::from(4u32); 139 | 140 | let enabled_var = FpVar::::new_input(cs.clone(), || Ok(enabled)).unwrap(); 141 | let target_var = FpVar::::new_input(cs.clone(), || Ok(target)).unwrap(); 142 | let set_var = Vec::>::new_input(cs.clone(), || Ok(set)).unwrap(); 143 | 144 | let set_gadget = SetGadget::new(set_var); 145 | let is_member = set_gadget 146 | .check_membership_enabled(&target_var, &enabled_var) 147 | .unwrap(); 148 | 149 | is_member.enforce_equal(&Boolean::TRUE).unwrap(); 150 | 151 | assert!(!cs.is_satisfied().unwrap()); 152 | } 153 | 154 | #[test] 155 | fn should_verify_set_membership_if_not_enabled() { 156 | let cs = ConstraintSystem::::new_ref(); 157 | 158 | // enable == 0 == false 159 | // Which means everything will evaluate to true, meaning it is in the set 160 | let enabled = Fr::from(0u32); 161 | let set = vec![Fr::from(1u32), Fr::from(2u32), Fr::from(3u32)]; 162 | let target = Fr::from(4u32); 163 | 164 | let enabled_var = FpVar::::new_input(cs.clone(), || Ok(enabled)).unwrap(); 165 | let target_var = FpVar::::new_input(cs.clone(), || Ok(target)).unwrap(); 166 | let set_var = Vec::>::new_input(cs.clone(), || Ok(set)).unwrap(); 167 | 168 | let set_gadget = SetGadget::new(set_var); 169 | let is_member = set_gadget 170 | .check_membership_enabled(&target_var, &enabled_var) 171 | .unwrap(); 172 | 173 | is_member.enforce_equal(&Boolean::TRUE).unwrap(); 174 | 175 | assert!(cs.is_satisfied().unwrap()); 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /arkworks-setups/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /arkworks-setups/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "arkworks-setups" 3 | version = "1.1.1" 4 | edition = "2021" 5 | license = "Apache-2.0" 6 | description = "Webb protocol's API for zero-knowledge circuits" 7 | repository = "https://github.com/webb-tools/arkworks-gadgets" 8 | homepage = "https://webb.tools" 9 | 10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 11 | 12 | [dependencies] 13 | arkworks-r1cs-circuits = { path = "../arkworks-r1cs-circuits", version = "1.0.0", default-features = false } 14 | arkworks-r1cs-gadgets = { path = "../arkworks-r1cs-gadgets", version = "1.0.0", default-features = false } 15 | arkworks-native-gadgets = { path = "../arkworks-native-gadgets", version = "1.0.0", default-features = false } 16 | 17 | ark-crypto-primitives = { version = "^0.3.0", features = ["r1cs"], default-features = false } 18 | ark-ff = { version = "^0.3.0", default-features = false } 19 | ark-std = { version = "^0.3.0", default-features = false } 20 | ark-r1cs-std = { version = "^0.3.0", default-features = false } 21 | ark-relations = { version = "^0.3.0", default-features = false } 22 | ark-ec = { version = "^0.3.0", default-features = false } 23 | ark-serialize = { version = "^0.3.0", default-features = false } 24 | ark-groth16 = { version = "^0.3.0", default-features = false } 25 | 26 | tiny-keccak = { version = "2.0.2", features = ["keccak"] } 27 | codec = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] } 28 | crypto_box = { version = "0.7.1", optional = true } 29 | 30 | tracing = { version = "0.1", default-features = false, features = [ "attributes" ], optional = true } 31 | tracing-subscriber = { version = "0.2", optional = true } 32 | 33 | [dependencies.arkworks-utils] 34 | path = "../arkworks-utils" 35 | version = "1.0.0" 36 | default-features = false 37 | features = ["poseidon_bn254_x5_2", "poseidon_bn254_x5_3", "poseidon_bn254_x5_4", "poseidon_bn254_x5_5"] 38 | 39 | [dev-dependencies] 40 | ark-snark = { version = "^0.3.0", default-features = false } 41 | digest = { version = "0.9" } 42 | 43 | # curves 44 | ark-bn254 = { version = "^0.3.0", default-features = false, features = [ "curve" ] } 45 | hex-literal = { version = "0.3.4" } 46 | 47 | [features] 48 | default = ["std", "r1cs"] 49 | aead = ["crypto_box"] 50 | r1cs = [] 51 | plonk = [] 52 | std = [ 53 | "arkworks-r1cs-circuits/std", 54 | "arkworks-r1cs-gadgets/std", 55 | "arkworks-native-gadgets/std", 56 | "ark-crypto-primitives/std", 57 | "ark-ff/std", 58 | "ark-std/std", 59 | "ark-r1cs-std/std", 60 | "ark-relations/std", 61 | "ark-ec/std", 62 | "ark-groth16/std", 63 | "ark-serialize/std", 64 | "arkworks-utils/std", 65 | "codec/std", 66 | ] 67 | parallel = [ 68 | "ark-crypto-primitives/parallel", 69 | "ark-std/parallel", 70 | "ark-r1cs-std/parallel", 71 | "ark-ec/parallel", 72 | "ark-groth16/parallel", 73 | "ark-ff/parallel", 74 | "arkworks-r1cs-circuits/parallel", 75 | "arkworks-r1cs-gadgets/parallel", 76 | "arkworks-native-gadgets/parallel", 77 | ] 78 | trace = [ 79 | "tracing", 80 | "tracing-subscriber", 81 | ] 82 | -------------------------------------------------------------------------------- /arkworks-setups/src/aead.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | keypair::{Keypair, KeypairError}, 3 | utxo::{Utxo, UtxoError}, 4 | }; 5 | use ark_crypto_primitives::Error; 6 | use ark_ff::{to_bytes, PrimeField}; 7 | use ark_std::{ 8 | convert::TryInto, 9 | rand::{CryptoRng, RngCore}, 10 | vec::Vec, 11 | }; 12 | use arkworks_native_gadgets::poseidon::FieldHasher; 13 | use codec::{Decode, Encode}; 14 | use crypto_box::{ 15 | aead::{generic_array::GenericArray, Aead, AeadCore, Payload}, 16 | generate_nonce, PublicKey, SalsaBox, SecretKey, 17 | }; 18 | 19 | type NonceSize = ::NonceSize; 20 | type Nonce = GenericArray; 21 | pub struct EncryptedData { 22 | pub nonce: Nonce, 23 | pub ephemeral_pk: PublicKey, 24 | pub cypher_text: Vec, 25 | } 26 | 27 | impl Decode for EncryptedData { 28 | fn decode(input: &mut I) -> Result { 29 | // Getting the size of Nonce 30 | const NONCE_LEN: usize = core::mem::size_of::(); 31 | // Getting the size of pub key 32 | const PUB_KEY_LEN: usize = core::mem::size_of::(); 33 | let mut nonce_data = [0u8; NONCE_LEN]; 34 | let mut ephemeral_pk_data = [0u8; PUB_KEY_LEN]; 35 | 36 | // Reading the data for nonce and public key 37 | input.read(&mut nonce_data)?; 38 | input.read(&mut ephemeral_pk_data)?; 39 | 40 | // Getting the length of the remaining data 41 | let remaining_len: usize = input.remaining_len()?.unwrap_or(0usize); 42 | let mut cypher_text_data = vec![0u8; remaining_len]; 43 | 44 | // Use the remaining data as cypher text 45 | input.read(&mut cypher_text_data)?; 46 | 47 | let nonce: Nonce = *GenericArray::::from_slice(&nonce_data); 48 | let ephemeral_pk: PublicKey = PublicKey::from(ephemeral_pk_data); 49 | let cypher_text = cypher_text_data.to_vec(); 50 | 51 | Ok(Self { 52 | nonce, 53 | ephemeral_pk, 54 | cypher_text, 55 | }) 56 | } 57 | } 58 | impl Encode for EncryptedData { 59 | fn encode(&self) -> Vec { 60 | const NONCE_LEN: usize = core::mem::size_of::(); 61 | const PUB_KEY_LEN: usize = core::mem::size_of::(); 62 | 63 | // Initialize return array 64 | let mut ret = vec![0u8; self.encoded_size()]; 65 | 66 | // Populate it with data 67 | ret[0..NONCE_LEN].copy_from_slice(&self.nonce.as_slice()); 68 | ret[NONCE_LEN..(NONCE_LEN + PUB_KEY_LEN)].copy_from_slice(self.ephemeral_pk.as_bytes()); 69 | ret[(NONCE_LEN + PUB_KEY_LEN)..].copy_from_slice(&self.cypher_text); 70 | 71 | ret 72 | } 73 | 74 | fn encoded_size(&self) -> usize { 75 | const NONCE_LEN: usize = core::mem::size_of::(); 76 | const PUB_KEY_LEN: usize = core::mem::size_of::(); 77 | let cypher_text_len = self.cypher_text.len(); 78 | NONCE_LEN + PUB_KEY_LEN + cypher_text_len 79 | } 80 | } 81 | 82 | impl> Keypair { 83 | pub fn encrypt( 84 | &self, 85 | msg: &[u8], 86 | rng: &mut R, 87 | ) -> Result { 88 | // Generate new nonce 89 | let nonce = generate_nonce(rng); 90 | 91 | // Convert private key into bytes array 92 | let secret_key_bytes = to_bytes!(self.secret_key)?; 93 | let sc_bytes: [u8; 32] = secret_key_bytes 94 | .try_into() 95 | .map_err(|_| KeypairError::SecretKeyParseFailed)?; 96 | 97 | // Generate public key from secret key 98 | // QUESTION: Should we derive the public key with poseidon.hash(secret_key)? 99 | let secret_key = SecretKey::from(sc_bytes); 100 | let public_key = PublicKey::from(&secret_key); 101 | 102 | // Generate ephemeral sk/pk 103 | let ephemeral_sk = SecretKey::generate(rng); 104 | let ephemeral_pk = PublicKey::from(&ephemeral_sk); 105 | 106 | let my_box = SalsaBox::new(&public_key, &ephemeral_sk); 107 | 108 | // Encrypting the message 109 | let ct = my_box 110 | .encrypt(&nonce, Payload { 111 | msg: &msg, 112 | aad: &[], 113 | }) 114 | .map_err::(|_| KeypairError::EncryptionFailed.into())?; 115 | 116 | Ok(EncryptedData { 117 | nonce, 118 | cypher_text: ct, 119 | ephemeral_pk, 120 | }) 121 | } 122 | 123 | pub fn decrypt(&self, encrypted_data: &EncryptedData) -> Result, Error> { 124 | // Creating a secret key 125 | let secret_key_bytes = to_bytes![self.secret_key]?; 126 | 127 | let sc_bytes: [u8; 32] = secret_key_bytes 128 | .try_into() 129 | .map_err(|_| KeypairError::SecretKeyParseFailed)?; 130 | let secret_key = SecretKey::from(sc_bytes); 131 | 132 | // Making ephemeral public key from the encryption data 133 | let my_box = SalsaBox::new(&encrypted_data.ephemeral_pk, &secret_key); 134 | 135 | // Converting nonce into proper type 136 | let nonce = GenericArray::from_slice(&encrypted_data.nonce); 137 | 138 | // Decrypt the cypher text, get the plaintext 139 | let plaintext = my_box 140 | .decrypt(&nonce, Payload { 141 | msg: &encrypted_data.cypher_text, 142 | aad: &[], 143 | }) 144 | .map_err::(|_| KeypairError::DecryptionFailed.into())?; 145 | Ok(plaintext) 146 | } 147 | } 148 | 149 | impl Utxo { 150 | pub fn encrypt(&self, rng: &mut R) -> Result, Error> { 151 | // We are encrypting the amount and the blinding 152 | let msg = to_bytes![self.chain_id, self.amount, self.blinding]?; 153 | // Encrypting the message 154 | let enc_data = self.keypair.encrypt(&msg, rng)?; 155 | 156 | Ok(enc_data.encode()) 157 | } 158 | 159 | pub fn decrypt(&self, data: &[u8]) -> Result<(Vec, Vec, Vec), Error> { 160 | let decoded_ed = EncryptedData::decode(&mut &data[..]) 161 | .map_err(|_| UtxoError::EncryptedDataDecodeError)?; 162 | // Decrypting the message 163 | let plaintext = self.keypair.decrypt(&decoded_ed)?; 164 | 165 | // First 32 bytes is chain id 166 | let chain_id = plaintext[..32].to_vec(); 167 | // Second 32 bytes is amount 168 | let amount = plaintext[32..64].to_vec(); 169 | // Third 32 bytes is blinding 170 | let blinding = plaintext[64..96].to_vec(); 171 | 172 | Ok((chain_id, amount, blinding)) 173 | } 174 | } 175 | 176 | #[cfg(test)] 177 | mod test { 178 | use crate::common::setup_params; 179 | use ark_bn254::Fr; 180 | use ark_ff::{BigInteger, PrimeField}; 181 | use ark_std::{test_rng, UniformRand}; 182 | use arkworks_native_gadgets::poseidon::Poseidon; 183 | use arkworks_utils::Curve; 184 | use codec::{Decode, Encode}; 185 | 186 | use super::EncryptedData; 187 | use crate::{keypair::Keypair, utxo::Utxo}; 188 | 189 | #[test] 190 | fn should_encrypt_decrypt() { 191 | let rng = &mut test_rng(); 192 | 193 | let private_key = Fr::rand(rng); 194 | let keypair = Keypair::>::new(private_key.clone()); 195 | 196 | let msg = vec![1, 2, 3]; 197 | let encrypted_data = keypair.encrypt(&msg, rng).unwrap(); 198 | let plaintext = keypair.decrypt(&encrypted_data).unwrap(); 199 | 200 | assert_eq!(plaintext, msg); 201 | } 202 | 203 | #[test] 204 | fn should_encode_decode_encrypted_data() { 205 | let rng = &mut test_rng(); 206 | 207 | let private_key = Fr::rand(rng); 208 | let keypair = Keypair::>::new(private_key.clone()); 209 | 210 | let msg = vec![1, 2, 3]; 211 | let encrypted_data = keypair.encrypt(&msg, rng).unwrap(); 212 | let encoded_ed = encrypted_data.encode(); 213 | let decoded_ed = EncryptedData::decode(&mut &encoded_ed[..]).unwrap(); 214 | let plaintext = keypair.decrypt(&decoded_ed).unwrap(); 215 | 216 | assert_eq!(plaintext, msg); 217 | } 218 | 219 | #[test] 220 | fn test_utxo_encrypt() { 221 | let curve = Curve::Bn254; 222 | let params2 = setup_params::(curve, 5, 2); 223 | let params4 = setup_params::(curve, 5, 4); 224 | let params5 = setup_params::(curve, 5, 5); 225 | let poseidon2 = Poseidon::new(params2); 226 | let poseidon4 = Poseidon::new(params4); 227 | let poseidon5 = Poseidon::new(params5); 228 | 229 | let rng = &mut test_rng(); 230 | 231 | let chain_id_raw = 0u64; 232 | let chain_id = Fr::from(chain_id_raw); 233 | let amount = Fr::rand(rng); 234 | let blinding = Fr::rand(rng); 235 | // let utxo 236 | let utxo = Utxo::new( 237 | chain_id_raw, 238 | amount, 239 | None, 240 | None, 241 | Some(blinding), 242 | &poseidon2, 243 | &poseidon4, 244 | &poseidon5, 245 | rng, 246 | ) 247 | .unwrap(); 248 | 249 | let encrypted_data = utxo.encrypt(rng).unwrap(); 250 | let (chain_id_bytes, amount_bytes, blinding_bytes) = utxo.decrypt(&encrypted_data).unwrap(); 251 | 252 | assert_eq!(chain_id_bytes, chain_id.into_repr().to_bytes_le()); 253 | assert_eq!(amount_bytes, amount.into_repr().to_bytes_le()); 254 | assert_eq!(blinding_bytes, blinding.into_repr().to_bytes_le()); 255 | } 256 | } 257 | -------------------------------------------------------------------------------- /arkworks-setups/src/common.rs: -------------------------------------------------------------------------------- 1 | use ark_crypto_primitives::{Error, SNARK}; 2 | use ark_ec::PairingEngine; 3 | use ark_ff::fields::PrimeField; 4 | use ark_groth16::{Groth16, Proof, ProvingKey, VerifyingKey}; 5 | use ark_relations::r1cs::ConstraintSynthesizer; 6 | use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; 7 | use ark_std::{ 8 | collections::BTreeMap, 9 | rand::{CryptoRng, RngCore}, 10 | vec::Vec, 11 | }; 12 | use arkworks_native_gadgets::{ 13 | merkle_tree::{Path, SparseMerkleTree}, 14 | poseidon::{sbox::PoseidonSbox, FieldHasher, PoseidonParameters}, 15 | }; 16 | use arkworks_utils::{ 17 | bytes_matrix_to_f, bytes_vec_to_f, poseidon_params::setup_poseidon_params, Curve, 18 | }; 19 | use tiny_keccak::{Hasher, Keccak}; 20 | 21 | pub struct VAnchorLeaf { 22 | pub chain_id_bytes: Vec, 23 | pub amount: u128, 24 | pub public_key_bytes: Vec, 25 | pub blinding_bytes: Vec, 26 | pub index: u32, 27 | pub private_key_bytes: Vec, 28 | pub nullifier_bytes: Vec, 29 | pub leaf_bytes: Vec, 30 | pub nullifier_hash_bytes: Vec, 31 | } 32 | 33 | pub struct Leaf { 34 | pub chain_id_bytes: Option>, 35 | pub secret_bytes: Vec, 36 | pub nullifier_bytes: Vec, 37 | pub leaf_bytes: Vec, 38 | pub nullifier_hash_bytes: Vec, 39 | } 40 | 41 | pub struct VAnchorProof { 42 | pub proof: Vec, 43 | pub public_inputs_raw: Vec>, 44 | } 45 | 46 | pub struct AnchorProof { 47 | pub proof: Vec, 48 | pub leaf_raw: Vec, 49 | pub nullifier_hash_raw: Vec, 50 | pub roots_raw: Vec>, 51 | pub public_inputs_raw: Vec>, 52 | } 53 | 54 | pub struct MixerProof { 55 | pub proof: Vec, 56 | pub leaf_raw: Vec, 57 | pub nullifier_hash_raw: Vec, 58 | pub root_raw: Vec, 59 | pub public_inputs_raw: Vec>, 60 | } 61 | 62 | pub struct Keys { 63 | pub pk: Vec, 64 | pub vk: Vec, 65 | } 66 | 67 | pub fn setup_keys>( 68 | circuit: C, 69 | rng: &mut R, 70 | ) -> Result<(Vec, Vec), Error> { 71 | let (pk, vk) = Groth16::::circuit_specific_setup(circuit, rng)?; 72 | 73 | let mut pk_bytes = Vec::new(); 74 | let mut vk_bytes = Vec::new(); 75 | pk.serialize(&mut pk_bytes)?; 76 | vk.serialize(&mut vk_bytes)?; 77 | Ok((pk_bytes, vk_bytes)) 78 | } 79 | 80 | pub fn setup_keys_unchecked< 81 | E: PairingEngine, 82 | R: RngCore + CryptoRng, 83 | C: ConstraintSynthesizer, 84 | >( 85 | circuit: C, 86 | rng: &mut R, 87 | ) -> Result<(Vec, Vec), Error> { 88 | let (pk, vk) = Groth16::::circuit_specific_setup(circuit, rng)?; 89 | 90 | let mut pk_bytes = Vec::new(); 91 | let mut vk_bytes = Vec::new(); 92 | pk.serialize_unchecked(&mut pk_bytes)?; 93 | vk.serialize_unchecked(&mut vk_bytes)?; 94 | Ok((pk_bytes, vk_bytes)) 95 | } 96 | 97 | pub fn prove>( 98 | circuit: C, 99 | pk_bytes: &[u8], 100 | rng: &mut R, 101 | ) -> Result, Error> { 102 | let pk = ProvingKey::::deserialize(pk_bytes)?; 103 | 104 | let proof = Groth16::prove(&pk, circuit, rng)?; 105 | let mut proof_bytes = Vec::new(); 106 | proof.serialize(&mut proof_bytes)?; 107 | Ok(proof_bytes) 108 | } 109 | 110 | pub fn prove_unchecked< 111 | E: PairingEngine, 112 | R: RngCore + CryptoRng, 113 | C: ConstraintSynthesizer, 114 | >( 115 | circuit: C, 116 | pk_unchecked_bytes: &[u8], 117 | rng: &mut R, 118 | ) -> Result, Error> { 119 | let pk = ProvingKey::::deserialize_unchecked(pk_unchecked_bytes)?; 120 | 121 | let proof = Groth16::prove(&pk, circuit, rng)?; 122 | let mut proof_bytes = Vec::new(); 123 | proof.serialize(&mut proof_bytes)?; 124 | Ok(proof_bytes) 125 | } 126 | 127 | pub fn verify( 128 | public_inputs: &[E::Fr], 129 | vk_bytes: &[u8], 130 | proof: &[u8], 131 | ) -> Result { 132 | let vk = VerifyingKey::::deserialize(vk_bytes)?; 133 | let proof = Proof::::deserialize(proof)?; 134 | verify_groth16(&vk, &public_inputs, &proof) 135 | } 136 | 137 | pub fn verify_unchecked( 138 | public_inputs: &[E::Fr], 139 | vk_unchecked_bytes: &[u8], 140 | proof: &[u8], 141 | ) -> Result { 142 | let vk = VerifyingKey::::deserialize_unchecked(vk_unchecked_bytes)?; 143 | let proof = Proof::::deserialize(proof)?; 144 | verify_groth16(&vk, &public_inputs, &proof) 145 | } 146 | 147 | pub fn verify_unchecked_raw( 148 | public_inputs: &[Vec], 149 | vk_unchecked_bytes: &[u8], 150 | proof: &[u8], 151 | ) -> Result { 152 | let pub_ins: Vec = public_inputs 153 | .iter() 154 | .map(|x| E::Fr::from_le_bytes_mod_order(&x)) 155 | .collect(); 156 | let vk = VerifyingKey::::deserialize_unchecked(vk_unchecked_bytes)?; 157 | let proof = Proof::::deserialize(proof)?; 158 | verify_groth16(&vk, &pub_ins, &proof) 159 | } 160 | 161 | pub fn verify_groth16( 162 | vk: &VerifyingKey, 163 | public_inputs: &[E::Fr], 164 | proof: &Proof, 165 | ) -> Result { 166 | let res = Groth16::::verify(vk, public_inputs, proof)?; 167 | Ok(res) 168 | } 169 | 170 | pub fn keccak_256(input: &[u8]) -> Vec { 171 | let mut keccak = Keccak::v256(); 172 | keccak.update(&input); 173 | 174 | let mut output = [0u8; 32]; 175 | keccak.finalize(&mut output); 176 | output.to_vec() 177 | } 178 | 179 | pub type SMT = SparseMerkleTree; 180 | 181 | pub fn create_merkle_tree, const N: usize>( 182 | hasher: &H, 183 | leaves: &[F], 184 | default_leaf: &[u8], 185 | ) -> SparseMerkleTree { 186 | let pairs: BTreeMap = leaves 187 | .iter() 188 | .enumerate() 189 | .map(|(i, l)| (i as u32, *l)) 190 | .collect(); 191 | let smt = SparseMerkleTree::::new(&pairs, hasher, default_leaf).unwrap(); 192 | 193 | smt 194 | } 195 | 196 | pub fn setup_tree_and_create_path, const HEIGHT: usize>( 197 | hasher: &H, 198 | leaves: &[F], 199 | index: u64, 200 | default_leaf: &[u8], 201 | ) -> Result<(SMT, Path), Error> { 202 | // Making the merkle tree 203 | let smt = create_merkle_tree::(hasher, leaves, default_leaf); 204 | // Getting the proof path 205 | let path = smt.generate_membership_proof(index); 206 | Ok((smt, path)) 207 | } 208 | 209 | pub fn setup_params(curve: Curve, exp: i8, width: u8) -> PoseidonParameters { 210 | let pos_data = setup_poseidon_params(curve, exp, width).unwrap(); 211 | 212 | let mds_f = bytes_matrix_to_f(&pos_data.mds); 213 | let rounds_f = bytes_vec_to_f(&pos_data.rounds); 214 | 215 | let pos = PoseidonParameters { 216 | mds_matrix: mds_f, 217 | round_keys: rounds_f, 218 | full_rounds: pos_data.full_rounds, 219 | partial_rounds: pos_data.partial_rounds, 220 | sbox: PoseidonSbox(pos_data.exp), 221 | width: pos_data.width, 222 | }; 223 | 224 | pos 225 | } 226 | -------------------------------------------------------------------------------- /arkworks-setups/src/keypair.rs: -------------------------------------------------------------------------------- 1 | use ark_crypto_primitives::Error; 2 | use ark_ff::PrimeField; 3 | use ark_std::{error::Error as ArkError, marker::PhantomData, string::ToString}; 4 | use arkworks_native_gadgets::poseidon::FieldHasher; 5 | 6 | #[derive(Debug)] 7 | pub enum KeypairError { 8 | EncryptionFailed, 9 | DecryptionFailed, 10 | SecretKeyParseFailed, 11 | DecodeFailed, 12 | EncodeFailed, 13 | } 14 | 15 | impl core::fmt::Display for KeypairError { 16 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 17 | let msg = match self { 18 | KeypairError::EncryptionFailed => "Data encryption failed".to_string(), 19 | KeypairError::DecryptionFailed => "Data decryption failed".to_string(), 20 | KeypairError::SecretKeyParseFailed => "Failed to parse secret key".to_string(), 21 | KeypairError::DecodeFailed => "Failed to decode encrypted data".to_string(), 22 | KeypairError::EncodeFailed => "Failed to encode encrypted data".to_string(), 23 | }; 24 | write!(f, "{}", msg) 25 | } 26 | } 27 | 28 | impl ArkError for KeypairError {} 29 | 30 | #[derive(Default, Debug, Copy)] 31 | pub struct Keypair> { 32 | pub secret_key: F, 33 | _h: PhantomData, 34 | } 35 | 36 | impl> Keypair { 37 | pub fn new(secret_key: F) -> Self { 38 | Self { 39 | secret_key, 40 | _h: PhantomData, 41 | } 42 | } 43 | 44 | pub fn public_key(&self, hasher2: &H) -> Result { 45 | let res = hasher2.hash(&[self.secret_key])?; 46 | Ok(res) 47 | } 48 | 49 | // Computes the signature = hash(privKey, commitment, pathIndices) 50 | pub fn signature(&self, commitment: &F, index: &F, hasher4: &H) -> Result { 51 | let res = hasher4.hash(&[self.secret_key.clone(), commitment.clone(), index.clone()])?; 52 | Ok(res) 53 | } 54 | } 55 | 56 | impl> Clone for Keypair { 57 | fn clone(&self) -> Self { 58 | let secret_key = self.secret_key.clone(); 59 | Self::new(secret_key) 60 | } 61 | } 62 | 63 | #[cfg(test)] 64 | mod test { 65 | use crate::common::setup_params; 66 | use ark_bn254::Fq; 67 | use ark_std::{test_rng, UniformRand, Zero}; 68 | use arkworks_native_gadgets::poseidon::{FieldHasher, Poseidon}; 69 | use arkworks_utils::Curve; 70 | 71 | use super::Keypair; 72 | 73 | #[test] 74 | fn should_crate_new_public_key() { 75 | let rng = &mut test_rng(); 76 | let curve = Curve::Bn254; 77 | 78 | let params = setup_params(curve, 5, 2); 79 | let hasher = Poseidon::::new(params.clone()); 80 | let private_key = Fq::rand(rng); 81 | 82 | let pubkey = hasher.hash(&[private_key]).unwrap(); 83 | 84 | let keypair = Keypair::>::new(private_key.clone()); 85 | let new_pubkey = keypair.public_key(&hasher).unwrap(); 86 | 87 | assert_eq!(new_pubkey, pubkey) 88 | } 89 | #[test] 90 | fn should_crate_new_signature() { 91 | let rng = &mut test_rng(); 92 | let index = Fq::zero(); 93 | let private_key = Fq::rand(rng); 94 | let curve = Curve::Bn254; 95 | 96 | let params4 = setup_params(curve, 5, 4); 97 | let hasher = Poseidon::::new(params4.clone()); 98 | let commitment = Fq::rand(rng); 99 | 100 | let keypair = Keypair::>::new(private_key.clone()); 101 | 102 | // Since signature = hash(privKey, commitment, pathIndices) 103 | let ev_res = hasher.hash(&[private_key, commitment, index]).unwrap(); 104 | let signature = keypair.signature(&commitment, &index, &hasher).unwrap(); 105 | assert_eq!(ev_res, signature); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /arkworks-setups/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | use ark_std::collections::BTreeMap; 3 | 4 | use ark_crypto_primitives::Error; 5 | use ark_ec::PairingEngine; 6 | use ark_ff::{PrimeField, SquareRootField}; 7 | use ark_std::{ 8 | rand::{CryptoRng, RngCore}, 9 | vec::Vec, 10 | }; 11 | 12 | pub use arkworks_utils::Curve; 13 | use common::{AnchorProof, Leaf, MixerProof, VAnchorProof}; 14 | use utxo::Utxo; 15 | 16 | #[cfg(feature = "aead")] 17 | pub mod aead; 18 | 19 | pub mod common; 20 | pub mod keypair; 21 | pub mod utxo; 22 | 23 | #[cfg(feature = "r1cs")] 24 | pub mod r1cs; 25 | 26 | #[cfg(feature = "plonk")] 27 | pub mod plonk; 28 | 29 | pub trait MixerProver { 30 | // For creating leaves where we supply the secret and the nullifier, for 31 | // generating new values, pass None 32 | fn create_leaf_with_privates( 33 | curve: Curve, 34 | secret: Vec, 35 | nullifier: Vec, 36 | ) -> Result; 37 | /// Create random leaf 38 | fn create_random_leaf(curve: Curve, rng: &mut R) 39 | -> Result; 40 | // For making proofs 41 | fn create_proof( 42 | curve: Curve, 43 | secret: Vec, 44 | nullifier: Vec, 45 | leaves: Vec>, 46 | index: u64, 47 | recipient: Vec, 48 | relayer: Vec, 49 | fee: u128, 50 | refund: u128, 51 | pk: Vec, 52 | default_leaf: [u8; 32], 53 | rng: &mut R, 54 | ) -> Result; 55 | } 56 | 57 | pub trait AnchorProver { 58 | // For creating leaves where we supply the chain_id, secret and the nullifier, 59 | // for generating new values, pass None 60 | fn create_leaf_with_privates( 61 | curve: Curve, 62 | chain_id: u64, 63 | secret: Vec, 64 | nullifier: Vec, 65 | ) -> Result; 66 | /// Create random leaf 67 | fn create_random_leaf( 68 | curve: Curve, 69 | chain_id: u64, 70 | rng: &mut R, 71 | ) -> Result; 72 | // For making proofs 73 | fn create_proof( 74 | curve: Curve, 75 | chain_id: u64, 76 | secret: Vec, 77 | nullifier: Vec, 78 | leaves: Vec>, 79 | index: u64, 80 | root_set: [Vec; ANCHOR_CT], 81 | recipient: Vec, 82 | relayer: Vec, 83 | fee: u128, 84 | refund: u128, 85 | commitment: Vec, 86 | pk: Vec, 87 | default_leaf: [u8; 32], 88 | rng: &mut R, 89 | ) -> Result; 90 | } 91 | 92 | pub trait VAnchorProver< 93 | E: PairingEngine, 94 | const HEIGHT: usize, 95 | const ANCHOR_CT: usize, 96 | const INS: usize, 97 | const OUTS: usize, 98 | > where 99 | ::Fr: PrimeField + SquareRootField + From, 100 | { 101 | fn create_leaf_with_privates( 102 | curve: Curve, 103 | chain_id: u64, 104 | amount: u128, 105 | index: Option, 106 | private_key: Vec, 107 | blinding: Vec, 108 | ) -> Result, Error> { 109 | Self::create_utxo(curve, chain_id, amount, index, private_key, blinding) 110 | } 111 | /// Create random leaf 112 | fn create_random_leaf( 113 | curve: Curve, 114 | chain_id: u64, 115 | amount: u128, 116 | index: Option, 117 | rng: &mut R, 118 | ) -> Result, Error> { 119 | Self::create_random_utxo(curve, chain_id, amount, index, rng) 120 | } 121 | /// For creating UTXO from all the secrets already generated 122 | fn create_utxo( 123 | curve: Curve, 124 | chain_id: u64, 125 | amount: u128, 126 | index: Option, 127 | private_key: Vec, 128 | blinding: Vec, 129 | ) -> Result, Error>; 130 | /// For creating UTXO from all the secrets already generated 131 | fn create_random_utxo( 132 | curve: Curve, 133 | chain_id: u64, 134 | amount: u128, 135 | index: Option, 136 | rng: &mut R, 137 | ) -> Result, Error>; 138 | /// For making proofs 139 | fn create_proof( 140 | curve: Curve, 141 | chain_id: u64, 142 | // External data 143 | public_amount: i128, 144 | ext_data_hash: Vec, 145 | in_root_set: [Vec; ANCHOR_CT], 146 | in_indices: [u64; INS], 147 | in_leaves: BTreeMap>>, 148 | // Input transactions 149 | in_utxos: [Utxo; INS], 150 | // Output transactions 151 | out_utxos: [Utxo; OUTS], 152 | pk: Vec, 153 | default_leaf: [u8; 32], 154 | rng: &mut R, 155 | ) -> Result; 156 | } 157 | -------------------------------------------------------------------------------- /arkworks-setups/src/plonk/mod.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /arkworks-setups/src/r1cs/mixer/mod.rs: -------------------------------------------------------------------------------- 1 | use crate::common::{Leaf, MixerProof}; 2 | use ark_crypto_primitives::Error; 3 | use ark_ec::PairingEngine; 4 | use ark_ff::{BigInteger, PrimeField}; 5 | use ark_std::{ 6 | marker::PhantomData, 7 | rand::{CryptoRng, RngCore}, 8 | vec, 9 | vec::Vec, 10 | UniformRand, 11 | }; 12 | use arkworks_native_gadgets::{ 13 | merkle_tree::Path, 14 | poseidon::{FieldHasher, Poseidon}, 15 | }; 16 | use arkworks_r1cs_circuits::mixer::MixerCircuit; 17 | use arkworks_r1cs_gadgets::poseidon::PoseidonGadget; 18 | use arkworks_utils::Curve; 19 | use codec::Encode; 20 | 21 | use crate::common::*; 22 | 23 | #[cfg(test)] 24 | mod tests; 25 | 26 | use crate::MixerProver; 27 | 28 | pub fn construct_public_inputs( 29 | nullifier_hash: F, 30 | root: F, 31 | arbitrary_input: F, 32 | ) -> Vec { 33 | vec![nullifier_hash, root, arbitrary_input] 34 | } 35 | 36 | pub fn deconstruct_public_inputs( 37 | public_inputs: &[F], 38 | ) -> ( 39 | F, // nullifier hash 40 | F, // root 41 | F, // recipient 42 | F, // relayer 43 | F, // fee 44 | F, // refund 45 | ) { 46 | ( 47 | public_inputs[0], 48 | public_inputs[1], 49 | public_inputs[2], 50 | public_inputs[3], 51 | public_inputs[4], 52 | public_inputs[6], 53 | ) 54 | } 55 | 56 | pub type PoseidonMixerCircuit = MixerCircuit, N>; 57 | 58 | pub struct MixerR1CSProver { 59 | engine: PhantomData, 60 | } 61 | 62 | impl MixerR1CSProver { 63 | #[allow(dead_code)] 64 | pub fn setup_random_circuit( 65 | curve: Curve, 66 | default_leaf: [u8; 32], 67 | rng: &mut R, 68 | ) -> Result< 69 | ( 70 | MixerCircuit, HEIGHT>, 71 | E::Fr, 72 | E::Fr, 73 | E::Fr, 74 | Vec, 75 | ), 76 | Error, 77 | > { 78 | let params3 = setup_params(curve, 5, 3); 79 | let poseidon = Poseidon::::new(params3.clone()); 80 | 81 | let arbitrary_input = E::Fr::rand(rng); 82 | // Generate the leaf 83 | let leaf = Self::create_random_leaf(curve, rng)?; 84 | let leaf_value = E::Fr::from_le_bytes_mod_order(&leaf.leaf_bytes); 85 | 86 | let secret = E::Fr::from_le_bytes_mod_order(&leaf.secret_bytes); 87 | let nullifier = E::Fr::from_le_bytes_mod_order(&leaf.nullifier_bytes); 88 | 89 | let nullifier_hash = E::Fr::from_le_bytes_mod_order(&leaf.nullifier_hash_bytes); 90 | let leaves = vec![E::Fr::from_le_bytes_mod_order(&leaf.leaf_bytes)]; 91 | let (tree, path) = setup_tree_and_create_path::, HEIGHT>( 92 | &poseidon, 93 | &leaves, 94 | 0, 95 | &default_leaf, 96 | )?; 97 | let root = tree.root(); 98 | 99 | let mc = MixerCircuit::, HEIGHT>::new( 100 | arbitrary_input, 101 | secret, 102 | nullifier, 103 | path, 104 | root, 105 | nullifier_hash, 106 | poseidon, 107 | ); 108 | let public_inputs = construct_public_inputs(nullifier_hash, root, arbitrary_input); 109 | 110 | Ok((mc, leaf_value, nullifier_hash, root, public_inputs)) 111 | } 112 | 113 | #[allow(dead_code)] 114 | pub fn setup_circuit_with_privates( 115 | curve: Curve, 116 | secret: E::Fr, 117 | nullifier: E::Fr, 118 | leaves: &[E::Fr], 119 | index: u64, 120 | arbitrary_input: E::Fr, 121 | default_leaf: [u8; 32], 122 | ) -> Result< 123 | ( 124 | MixerCircuit, HEIGHT>, 125 | E::Fr, 126 | E::Fr, 127 | E::Fr, 128 | Vec, 129 | ), 130 | Error, 131 | > { 132 | // Initialize hasher 133 | let params3 = setup_params(curve, 5, 3); 134 | let poseidon = Poseidon::::new(params3.clone()); 135 | // Setup inputs 136 | let leaf = poseidon.hash_two(&secret, &nullifier)?; 137 | let nullifier_hash = poseidon.hash_two(&nullifier, &nullifier)?; 138 | let (tree, path) = setup_tree_and_create_path::, HEIGHT>( 139 | &poseidon, 140 | &leaves, 141 | index, 142 | &default_leaf, 143 | )?; 144 | let root = tree.root(); 145 | 146 | let mc = MixerCircuit::, HEIGHT>::new( 147 | arbitrary_input, 148 | secret, 149 | nullifier, 150 | path, 151 | root, 152 | nullifier_hash, 153 | poseidon, 154 | ); 155 | let public_inputs = construct_public_inputs(nullifier_hash, root, arbitrary_input); 156 | Ok((mc, leaf, nullifier_hash, root, public_inputs)) 157 | } 158 | 159 | #[allow(clippy::too_many_arguments)] 160 | #[allow(dead_code)] 161 | pub fn setup_circuit_with_privates_raw( 162 | curve: Curve, 163 | secret: Vec, 164 | nullifier: Vec, 165 | leaves: &[Vec], 166 | index: u64, 167 | recipient: Vec, 168 | relayer: Vec, 169 | fee: u128, 170 | refund: u128, 171 | default_leaf: [u8; 32], 172 | ) -> Result< 173 | ( 174 | MixerCircuit, HEIGHT>, 175 | Vec, 176 | Vec, 177 | Vec, 178 | Vec>, 179 | ), 180 | Error, 181 | > { 182 | let secret_f = E::Fr::from_le_bytes_mod_order(&secret); 183 | let nullifier_f = E::Fr::from_le_bytes_mod_order(&nullifier); 184 | let leaves_f: Vec = leaves 185 | .iter() 186 | .map(|x| E::Fr::from_le_bytes_mod_order(x)) 187 | .collect(); 188 | 189 | let mut arbitrary_data_bytes = Vec::new(); 190 | arbitrary_data_bytes.extend(&recipient); 191 | arbitrary_data_bytes.extend(&relayer); 192 | // Using encode to be compatible with on chain types 193 | arbitrary_data_bytes.extend(fee.encode()); 194 | arbitrary_data_bytes.extend(refund.encode()); 195 | let arbitrary_data = keccak_256(&arbitrary_data_bytes); 196 | let arbitrary_input = E::Fr::from_le_bytes_mod_order(&arbitrary_data); 197 | 198 | let (mc, leaf, nullifier_hash, root, public_inputs) = Self::setup_circuit_with_privates( 199 | curve, 200 | secret_f, 201 | nullifier_f, 202 | &leaves_f, 203 | index, 204 | arbitrary_input, 205 | default_leaf, 206 | )?; 207 | 208 | let leaf_raw = leaf.into_repr().to_bytes_le(); 209 | let nullifier_hash_raw = nullifier_hash.into_repr().to_bytes_le(); 210 | let root_raw = root.into_repr().to_bytes_le(); 211 | let public_inputs_raw: Vec> = public_inputs 212 | .iter() 213 | .map(|x| x.into_repr().to_bytes_le()) 214 | .collect(); 215 | 216 | Ok(( 217 | mc, 218 | leaf_raw, 219 | nullifier_hash_raw, 220 | root_raw, 221 | public_inputs_raw, 222 | )) 223 | } 224 | 225 | #[allow(dead_code)] 226 | pub fn create_circuit( 227 | curve: Curve, 228 | arbitrary_input: E::Fr, 229 | secret: E::Fr, 230 | nullifier: E::Fr, 231 | path: Path, HEIGHT>, 232 | root: E::Fr, 233 | nullifier_hash: E::Fr, 234 | ) -> MixerCircuit, HEIGHT> { 235 | // Initialize hasher 236 | let params3 = setup_params(curve, 5, 3); 237 | let poseidon = Poseidon::::new(params3.clone()); 238 | // Setup circuit 239 | let mc = MixerCircuit::new( 240 | arbitrary_input, 241 | secret, 242 | nullifier, 243 | path, 244 | root, 245 | nullifier_hash, 246 | poseidon, 247 | ); 248 | mc 249 | } 250 | } 251 | 252 | impl MixerProver for MixerR1CSProver { 253 | fn create_leaf_with_privates( 254 | curve: Curve, 255 | secret: Vec, 256 | nullifier: Vec, 257 | ) -> Result { 258 | let secret_field_elt: E::Fr = E::Fr::from_le_bytes_mod_order(&secret); 259 | let nullifier_field_elt: E::Fr = E::Fr::from_le_bytes_mod_order(&nullifier); 260 | 261 | let params3 = setup_params(curve, 5, 3); 262 | let poseidon = Poseidon::::new(params3.clone()); 263 | let leaf_field_element = poseidon.hash_two(&secret_field_elt, &nullifier_field_elt)?; 264 | let nullifier_hash_field_element = 265 | poseidon.hash_two(&nullifier_field_elt, &nullifier_field_elt)?; 266 | Ok(Leaf { 267 | chain_id_bytes: None, 268 | secret_bytes: secret_field_elt.into_repr().to_bytes_le(), 269 | nullifier_bytes: nullifier_field_elt.into_repr().to_bytes_le(), 270 | leaf_bytes: leaf_field_element.into_repr().to_bytes_le(), 271 | nullifier_hash_bytes: nullifier_hash_field_element.into_repr().to_bytes_le(), 272 | }) 273 | } 274 | 275 | fn create_proof( 276 | curve: Curve, 277 | secret: Vec, 278 | nullifier: Vec, 279 | leaves: Vec>, 280 | index: u64, 281 | recipient: Vec, 282 | relayer: Vec, 283 | fee: u128, 284 | refund: u128, 285 | pk: Vec, 286 | default_leaf: [u8; 32], 287 | rng: &mut R, 288 | ) -> Result { 289 | let params3 = setup_params(curve, 5, 3); 290 | let poseidon = Poseidon::::new(params3.clone()); 291 | // Get field element version of all the data 292 | let secret_f = E::Fr::from_le_bytes_mod_order(&secret); 293 | let nullifier_f = E::Fr::from_le_bytes_mod_order(&nullifier); 294 | let leaves_f: Vec = leaves 295 | .iter() 296 | .map(|x| E::Fr::from_le_bytes_mod_order(x)) 297 | .collect(); 298 | 299 | let mut arbitrary_data_bytes = Vec::new(); 300 | arbitrary_data_bytes.extend(&recipient); 301 | arbitrary_data_bytes.extend(&relayer); 302 | // Using encode to be compatible with on chain types 303 | arbitrary_data_bytes.extend(fee.encode()); 304 | arbitrary_data_bytes.extend(refund.encode()); 305 | let arbitrary_data = keccak_256(&arbitrary_data_bytes); 306 | let arbitrary_input = E::Fr::from_le_bytes_mod_order(&arbitrary_data); 307 | // Generate the leaf 308 | let Leaf { 309 | leaf_bytes, 310 | nullifier_hash_bytes, 311 | .. 312 | } = Self::create_leaf_with_privates(curve, secret, nullifier)?; 313 | // Setup the tree and generate the path 314 | let (tree, path) = setup_tree_and_create_path::, HEIGHT>( 315 | &poseidon, 316 | &leaves_f, 317 | index, 318 | &default_leaf, 319 | )?; 320 | let root = tree.root(); 321 | 322 | let nullifier_hash_f = E::Fr::from_le_bytes_mod_order(&nullifier_hash_bytes); 323 | let mc = MixerCircuit::, HEIGHT>::new( 324 | arbitrary_input, 325 | secret_f, 326 | nullifier_f, 327 | path, 328 | root, 329 | nullifier_hash_f, 330 | poseidon, 331 | ); 332 | let public_inputs = construct_public_inputs(nullifier_hash_f, root, arbitrary_input); 333 | 334 | let leaf_raw = leaf_bytes; 335 | let nullifier_hash_raw = nullifier_hash_bytes; 336 | let root_raw = root.into_repr().to_bytes_le(); 337 | let public_inputs_raw: Vec> = public_inputs 338 | .iter() 339 | .map(|x| x.into_repr().to_bytes_le()) 340 | .collect(); 341 | 342 | let proof = prove_unchecked::(mc, &pk, rng)?; 343 | 344 | Ok(MixerProof { 345 | leaf_raw, 346 | nullifier_hash_raw, 347 | root_raw, 348 | public_inputs_raw, 349 | proof, 350 | }) 351 | } 352 | 353 | fn create_random_leaf( 354 | curve: Curve, 355 | rng: &mut R, 356 | ) -> Result { 357 | let secret = E::Fr::rand(rng); 358 | let nullifier = E::Fr::rand(rng); 359 | Self::create_leaf_with_privates( 360 | curve, 361 | secret.into_repr().to_bytes_le(), 362 | nullifier.into_repr().to_bytes_le(), 363 | ) 364 | } 365 | } 366 | -------------------------------------------------------------------------------- /arkworks-setups/src/r1cs/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod anchor; 2 | pub mod mixer; 3 | pub mod vanchor; 4 | -------------------------------------------------------------------------------- /arkworks-setups/src/utxo.rs: -------------------------------------------------------------------------------- 1 | use crate::keypair::Keypair; 2 | use ark_crypto_primitives::Error; 3 | use ark_ff::PrimeField; 4 | use ark_std::{error::Error as ArkError, rand::RngCore, string::ToString}; 5 | use arkworks_native_gadgets::poseidon::{FieldHasher, Poseidon}; 6 | 7 | #[derive(Debug)] 8 | pub enum UtxoError { 9 | NullifierNotCalculated, 10 | EncryptedDataDecodeError, 11 | IndexNotSet, 12 | } 13 | 14 | impl core::fmt::Display for UtxoError { 15 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 16 | let msg = match self { 17 | UtxoError::NullifierNotCalculated => "Nullifier not calculated".to_string(), 18 | UtxoError::EncryptedDataDecodeError => "Failed to decode encrypted data".to_string(), 19 | &UtxoError::IndexNotSet => "Utxo index not set".to_string(), 20 | }; 21 | write!(f, "{}", msg) 22 | } 23 | } 24 | 25 | impl ArkError for UtxoError {} 26 | 27 | #[derive(Clone)] 28 | pub struct Utxo { 29 | pub chain_id_raw: u64, 30 | pub chain_id: F, 31 | pub amount: F, 32 | pub blinding: F, 33 | pub keypair: Keypair>, 34 | pub index: Option, 35 | pub nullifier: Option, 36 | pub commitment: F, 37 | } 38 | 39 | impl Utxo { 40 | pub fn new( 41 | chain_id_raw: u64, 42 | amount: F, 43 | index: Option, 44 | private_key: Option, 45 | blinding: Option, 46 | hasher2: &Poseidon, 47 | hasher4: &Poseidon, 48 | hasher5: &Poseidon, 49 | rng: &mut R, 50 | ) -> Result { 51 | let chain_id = F::from(chain_id_raw); 52 | let blinding = blinding.unwrap_or(F::rand(rng)); 53 | 54 | let private_key = private_key.unwrap_or(F::rand(rng)); 55 | let keypair = Keypair::new(private_key); 56 | 57 | let pub_key = keypair.public_key(hasher2)?; 58 | 59 | let leaf = hasher5.hash(&[chain_id, amount, pub_key, blinding])?; 60 | 61 | let nullifier = if index.is_some() { 62 | let i = F::from(index.unwrap()); 63 | 64 | let signature = keypair.signature(&leaf, &i, hasher4)?; 65 | // Nullifier 66 | let nullifier = hasher4.hash(&[leaf, i, signature])?; 67 | 68 | Some(nullifier) 69 | } else { 70 | None 71 | }; 72 | 73 | Ok(Self { 74 | chain_id_raw, 75 | chain_id, 76 | amount, 77 | keypair, 78 | blinding, 79 | index, 80 | nullifier, 81 | commitment: leaf, 82 | }) 83 | } 84 | 85 | pub fn new_with_privates( 86 | chain_id_raw: u64, 87 | amount: F, 88 | index: Option, 89 | private_key: F, 90 | blinding: F, 91 | hasher2: &Poseidon, 92 | hasher4: &Poseidon, 93 | hasher5: &Poseidon, 94 | ) -> Result { 95 | let chain_id = F::from(chain_id_raw); 96 | let keypair = Keypair::new(private_key); 97 | 98 | let pub_key = keypair.public_key(hasher2)?; 99 | let leaf = hasher5.hash(&[chain_id, amount, pub_key, blinding])?; 100 | 101 | let nullifier = if index.is_some() { 102 | let i = F::from(index.unwrap()); 103 | 104 | let signature = keypair.signature(&leaf, &i, hasher4)?; 105 | // Nullifier 106 | let nullifier = hasher4.hash(&[leaf, i, signature])?; 107 | 108 | Some(nullifier) 109 | } else { 110 | None 111 | }; 112 | 113 | Ok(Self { 114 | chain_id_raw, 115 | chain_id, 116 | amount, 117 | keypair, 118 | blinding, 119 | index, 120 | nullifier, 121 | commitment: leaf, 122 | }) 123 | } 124 | 125 | pub fn set_index(&mut self, index: u64, hasher4: &Poseidon) -> Result<(), Error> { 126 | let i = F::from(index); 127 | 128 | let signature = self.keypair.signature(&self.commitment, &i, hasher4)?; 129 | // Nullifier 130 | let nullifier = hasher4.hash(&[self.commitment, i, signature])?; 131 | 132 | self.index = Some(index); 133 | self.nullifier = Some(nullifier); 134 | 135 | Ok(()) 136 | } 137 | 138 | pub fn get_nullifier(&self) -> Result { 139 | self.nullifier 140 | .ok_or(UtxoError::NullifierNotCalculated.into()) 141 | } 142 | 143 | pub fn get_index(&self) -> Result { 144 | self.index.ok_or(UtxoError::IndexNotSet.into()) 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /arkworks-utils/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /arkworks-utils/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "arkworks-utils" 3 | version = "1.0.1" 4 | authors = ["Webb Developers"] 5 | edition = "2018" 6 | description = "Webb protocol's utils for zero-knowledge gadgets and circuits" 7 | license = "Apache-2.0" 8 | repository = "https://github.com/webb-tools/arkworks-gadgets" 9 | homepage = "https://webb.tools" 10 | 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | hex = { version = "0.4", default-features = false, features = ["alloc"] } 15 | ark-std = { version = "^0.3.0", default-features = false } 16 | ark-ff = { version = "^0.3.0", default-features = false } 17 | 18 | [features] 19 | std = ["ark-std/std", "hex/std"] 20 | 21 | poseidon_bls381_x3_3 = [] 22 | poseidon_bls381_x3_5 = [] 23 | 24 | poseidon_bls381_x5_3 = [] 25 | poseidon_bls381_x5_5 = [] 26 | 27 | poseidon_bls381_x17_3 = [] 28 | poseidon_bls381_x17_5 = [] 29 | 30 | poseidon_bn254_x3_3 = [] 31 | poseidon_bn254_x3_5 = [] 32 | 33 | poseidon_bn254_x5_2 = [] 34 | poseidon_bn254_x5_3 = [] 35 | poseidon_bn254_x5_4 = [] 36 | poseidon_bn254_x5_5 = [] 37 | 38 | poseidon_bn254_x17_3 = [] 39 | poseidon_bn254_x17_5 = [] 40 | 41 | mimc_ed_on_bn254_220 = [] 42 | 43 | parallel = [ 44 | "ark-std/parallel", 45 | "ark-ff/parallel", 46 | ] 47 | -------------------------------------------------------------------------------- /arkworks-utils/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(not(feature = "std"), no_std)] 2 | 3 | #[macro_use] 4 | extern crate ark_std; 5 | 6 | use ark_ff::PrimeField; 7 | pub use ark_std::vec::Vec; 8 | pub use hex::FromHexError; 9 | 10 | pub mod mimc_params; 11 | pub mod poseidon_params; 12 | 13 | type Bytes = Vec; 14 | 15 | #[derive(Copy, Clone)] 16 | pub enum Curve { 17 | Bls381, 18 | Bn254, 19 | } 20 | 21 | pub fn decode_hex(s: &str) -> Result { 22 | let s = &s[2..]; 23 | hex::decode(s) 24 | } 25 | 26 | pub fn parse_vec(arr: Vec<&str>) -> Result, FromHexError> { 27 | let mut res = Vec::new(); 28 | for r in arr.iter() { 29 | res.push(decode_hex(r)?); 30 | } 31 | Ok(res) 32 | } 33 | 34 | pub fn parse_matrix(mds_entries: Vec>) -> Result>, FromHexError> { 35 | let width = mds_entries.len(); 36 | let mut mds = vec![vec![Vec::new(); width]; width]; 37 | for i in 0..width { 38 | for j in 0..width { 39 | mds[i][j] = decode_hex(mds_entries[i][j])?; 40 | } 41 | } 42 | Ok(mds) 43 | } 44 | 45 | pub fn bytes_vec_to_f(bytes_vec: &Vec>) -> Vec { 46 | bytes_vec 47 | .iter() 48 | .map(|x| F::from_be_bytes_mod_order(x)) 49 | .collect() 50 | } 51 | 52 | pub fn bytes_matrix_to_f(bytes_matrix: &Vec>>) -> Vec> { 53 | bytes_matrix.iter().map(|x| bytes_vec_to_f(x)).collect() 54 | } 55 | -------------------------------------------------------------------------------- /arkworks-utils/src/mimc_params/mod.rs: -------------------------------------------------------------------------------- 1 | use super::{parse_vec, Bytes, Curve, FromHexError}; 2 | 3 | pub use ark_std::vec::Vec; 4 | 5 | pub struct MimcData { 6 | pub constants: Vec, 7 | pub rounds: u16, 8 | pub width: u8, 9 | } 10 | 11 | impl MimcData { 12 | pub fn new(constants: Vec, rounds: u16, width: u8) -> Self { 13 | Self { 14 | constants, 15 | rounds, 16 | width, 17 | } 18 | } 19 | } 20 | 21 | pub fn setup_mimc_params(curve: Curve, rounds: u16, width: u8) -> Result { 22 | match (curve, rounds, width) { 23 | #[cfg(feature = "mimc_ed_on_bn254_220")] 24 | (Curve::Bn254, 220, 3) => { 25 | #[path = "./ed_on_bn254_220.rs"] 26 | pub mod ed_on_bn254_220; 27 | use ed_on_bn254_220::{CONSTANTS, MIMC_ROUNDS, WIDTH}; 28 | get_mimc_data(CONSTANTS, MIMC_ROUNDS, WIDTH) 29 | } 30 | _ => unimplemented!(), 31 | } 32 | } 33 | 34 | pub fn get_mimc_data(constants: &[&str], rounds: u16, width: u8) -> Result { 35 | let constants = parse_vec(constants.to_vec())?; 36 | Ok(MimcData::new(constants, rounds, width)) 37 | } 38 | -------------------------------------------------------------------------------- /arkworks-utils/src/poseidon_params/bls381_x17_3.rs: -------------------------------------------------------------------------------- 1 | // https://github.com/webb-tools/bulletproof-gadgets/tree/main/src/crypto_constants/data/poseidon 2 | 3 | // Parameter for: 4 | // exponentiation = 17 5 | // width = 3 6 | // full rounds = 8 7 | // partial rounds = 33 8 | // prime field = 9 | // 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 10 | 11 | // Sage script command: 12 | // sage generate_parameters_grain.sage 1 0 255 3 8 33 13 | // 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001 14 | pub const FULL_ROUNDS: u8 = 8; 15 | pub const PARTIAL_ROUNDS: u8 = 57; 16 | pub const WIDTH: u8 = 3; 17 | pub const EXPONENTIATION: i8 = 17; 18 | 19 | pub const ROUND_CONSTS: &[&str] = &[ 20 | "0x5d772b29f1d7b793e319457b3b07d48d21aeec2097aa56cd3e30f9af0bbc8d89", 21 | "0x201a8ace9938a4dccc38d35d5ca1576c7668b4694727d0a9e0b5f46ea5ee375d", 22 | "0x5d67a7b4e7af2fde75af9ef1ff2dcd3533611f43c38838eb8f7feb848afc78bb", 23 | "0x1870813d6f76123c9e8ebd0b488d53e430298ffe13ff4e1bb1682fe976059ad9", 24 | "0x2c821c4177b99f4577fe0b79163306aea6d13a7dc6e3e4dad75df6c01064c224", 25 | "0x2809d94c958a04ae9a990b2edd7068cc4ea52c84b0dc12fcceac167c8461cff9", 26 | "0x44955d7e59d9d096a1146f934b666d6272638b7e6435ef0d700f55eedd0fbd34", 27 | "0x49d161278155978d74a93f6ec706cfe710b9fee31217b5d31846b5d52d488dcb", 28 | "0x247f1a2f59f327e5e1f97695e5a1cdab102657e8679cf04d34c657bd11705fc5", 29 | "0x61902a4e734f0c4ba2c563e4539b4a663eb0116ffb196fa9de36cdd3e5ad2102", 30 | "0x378302692b4a1726e5ee3a26a0d4078ab44b3df36617731f83a0712dbba58e95", 31 | "0x06399c9ace112078cf013876ba22158d325ce5a4810aa5007c56341dc1032084", 32 | "0x506321d2a00f28c69d37c800d3dfbb493e9dd50ab2c3a1de90c36d333a51952c", 33 | "0x1d741c58942539e2a73f96f1f049fa8b8b0c1b21d1bebd69092b2c2a3ddab447", 34 | "0x452bfaedbcc3764779401bc0abdaa263f843a14842adc299d7e89321a7701834", 35 | "0x2039b972744b5f301c3bb96d15d58c66d9145be94c46c2c66bd86a3a3e39251e", 36 | "0x43e361fd2a833db5689292b4caf1d50e926600b9066bf3567e3cc1a0455dfea3", 37 | "0x6d778ba7e0eda990101c0f659aaa312def48cfa8898ce9fcd25404c144ad083d", 38 | "0x4ad66669c34c9c48619aff1960d60ff766b659bf08f0ec4edd6c7a12aaa8d821", 39 | "0x03075c36878b137024db9a081e8a33c294f376944669eb920e5401f118d5095a", 40 | "0x67fa41ff21b887cb2a1b76579281dc788bfc8968048d82f34617813874a5c0e2", 41 | "0x1ba5eeaa48834005b26c3d2160222566cfe159641fc7f677018f14c6272407fc", 42 | "0x576b72efe5775705d53cf011b87926f525ef33050e41ed6fc968840f57f442d6", 43 | "0x1940cd32d08c3b5788ae1893d1b66d8d58dcd04c49ed6d74112a59c80ac28b1f", 44 | "0x0cc6e9feedf57d43dae61bb534d3ce991d595472abc3b9b2dbaa6333e73748c6", 45 | "0x47e22cd739e867f0ba9bdd1209243160370294163b4ea8fbfef668b613e680ab", 46 | "0x11660762b6a1ad160bfbf7a737ac0167b06bac7ab9e97425cb69e7496a4f4034", 47 | "0x3c7536a816dec062472604ce4a7f1b95b40743bd03025afcccfe53b416d98831", 48 | "0x6dcca5f9d8ac6af2c4380e2eb3c30698a48fdc7e94028279cee7f7ca5b88c51b", 49 | "0x6e7b41929ef9f7c5b6d6557adfaa5328b20d1882586db8e3fb3f5233e4aa8f97", 50 | "0x1da2d7476c5ecd6d08218df30d20730fe8895d8f0cdbb635a589abf745dfeaed", 51 | "0x0792062e6869bce903ad4ea4adb617284ca3a50743475b10b946e1e87401149f", 52 | "0x51377b059d068a9d7b03b2d86045c8ddf396ef1d2d0e6064f9a53c263a844945", 53 | "0x3f0d13f5591ebf128504ed18478b82fbd31011e2b091e6ff7b6b2ec77c62f34f", 54 | "0x2cb9ede7aa9222c82330792c7b8acb0a7f9e54c3dbcdade6aeeff4be0a98a3f9", 55 | "0x0e56b5d5d051cc9fb6a552e176b607ec38cb95878e998d76aa5cbf2eda427bb4", 56 | "0x715f793ce2e8fee77430a30ac93209a58844f07aad6b9ce9a09a4dbcdbf79675", 57 | "0x3c35317c532f02a7d90798524c520877baf4789fd58ed35a8f92cc9b53ed4536", 58 | "0x3dfbccab23672f22310b97863ae2ae7def399d72449828c9868b3a05e280a91a", 59 | "0x22ba7c51db72f4c8636f248a3884600b5ea7fb1de0fe25983c9ec37af8f6b1e1", 60 | "0x0056d1c0564a91436cb7c93a382452dcc423325f1149074cb1bbfd14c5cea26b", 61 | "0x11990168d9f9c82614970d46a8619bce16ce56719f732738a0ca895dfec3ac63", 62 | "0x1d9e91fb65392b240cd7384454317c15283c2616a08a1609774dd8afcc8f7b87", 63 | "0x01bd923c8fcbbeeaa99c852a312e4ffa93a0e3491e94a341b912eb1049c47ba2", 64 | "0x46f9939145c053bd903a63de1ce9ef98928f420472a10b6472a0f6b6139ba620", 65 | "0x733c2546c12f32d3cda7df097318fc2d9eaeb77a497194003b655f5b72d47456", 66 | "0x50a743901d498a84e2cfbac32affb22a1c120d71afebcb5178653991d5497fa1", 67 | "0x296bebb1c3e6617ff5e8562661784f1c8a454c282db71efa81444fdecfcfd07b", 68 | "0x33cbef36d91e1df1418015eb22ff88ce94fba8f16703bfb1e3976a19842f5ef4", 69 | "0x492f250b2463e735d1e0867423ac73e146de10f030a9e30ea480c855697a0a08", 70 | "0x17fca1112858b0e9e187874ca8fbe96e30d3737d94a7442b05003b16f1692592", 71 | "0x1953add866dcb8ecad4869e4a306d553909ea9ad70c4cfb3f8550c4260fe4501", 72 | "0x0baaf5862854abf2dc803a6252f98423006ab4fa986ed7cf5c2a4dbc428e4beb", 73 | "0x4af71aace01a3dc3bc981eceb0422e407781bcd1392185d4502bd80db4b11c2d", 74 | "0x3b48b371bf6b8b8a0553b6b5023c85761dea42f5c4d300cc5267db07aa449f44", 75 | "0x45d43f82ba1cf0b055745432e9750828fabf39e24f39e870ebb9c656b35212d7", 76 | "0x431fc3e7ca0d01084cce1e34447e5de5c4c82581f318abc141751819059acd30", 77 | "0x0eccc9e2c36fa70aeab478035c06a621dad4362e56619e094912934a88ac3576", 78 | "0x06612b53133b0ef7790904ece018e5523506633a732acb8a98476ceed31404e3", 79 | "0x0f1494bebb916b7ab4082bfc6d47c7bc1cc1cf2199e6930d76f1f6e2bd2860bc", 80 | "0x50b31f09176465637b857b659343df3eb62d5f5eb7a1a2fc6c0ff5a2ea207a27", 81 | "0x4125090e1f9d716c920f32767b0f7b8ba047b7317e77de4c52237f57263da917", 82 | "0x3f6a1b715dff930d847cecc48cd1180eb9fe29b6d3e8750013ccd75d14878552", 83 | "0x67e098a1711e91f662d6bd4d0e1347fd96471ae628de49fcd71a683edc43fc87", 84 | "0x088051253577b086de932df084451b2b0c1904d0a169e5cf408bd7cba57a7c26", 85 | "0x3d1c8e7a1e36f24f121a5ac488bf6dc2b606fba40d09a8056c57a22fb8a67cbf", 86 | "0x1f453af47424f13d60ae974cb4bbac0941a4672aa4bc95472eb6b1d5805ece32", 87 | "0x09dc8eb7ec96061621a7b56f53c60e23379fff0e421e5e40b0f4457fda8905bb", 88 | "0x6edfc69d90684387b46b8fc7bc19b0f88abdce2f80d9681442eeda275beda310", 89 | "0x253ed42b4a972d05e974326b5bc12106996fc2092b81629fe444548fd230540c", 90 | "0x32a2264f8fbe68653e41a1967ef0938e262b6aac1f5c32a2dc4180a87c1b763b", 91 | "0x6c9a0a771efa001dd472fdbcf6304d5134f3baa97562c21e60bcb85f430c6caf", 92 | "0x0ce0377445e16ab2e07102287ee2f357636f7aabb9db7093bfcca3deb6372252", 93 | "0x3551b47f1007fe22ca965204b9068d73f6ad4e46e81bbd61a51e7bc4a159f21d", 94 | "0x2b75a1ac8dbe0f8a63d2916cd0fd56101d9a12bf207c58832cbf43864855a768", 95 | "0x6481f58b9f1afe48203f95887ec812f8efacd904c22f13adf0237ee6e377f80f", 96 | "0x51f4be64d9e9c27e9b5c66b99e46d256bdacee74402df3dea5fb9fc81134b9a9", 97 | "0x0306bf22d16953e1c7b54a06510145f2469aab2a3e3eb551d217d289611d0ac1", 98 | "0x06a237d9d633f20c7bf56c8f651add34118902b1ba17881835d9efa0b31908b6", 99 | "0x265d94ffb32eab2342a85c81ef1d18120d95fe3f8aa830555c8db11dad727263", 100 | "0x19a9f6a2aa1c9972bb973d082b2c283f93794e1319944044526846c61ddca141", 101 | "0x4e5b183e70bbe21cb0170d3bbf164952ca631dc194084f86f98fbc95e39ab7a3", 102 | "0x39920749c129d8ccfe986342730b7ce278205bd9602d7ffc18cc60d25617868e", 103 | "0x2c5de14a6f943d82cf9e5d6c0f097ebe91be70415570ca4cac5873a339a263dd", 104 | "0x5cb508d0399fc3185cebc1a12f58d7fa0045d32c712170fefe206f8dc60f96cc", 105 | "0x5e6d567222480dd53b93a9e73d66ac28c8a2755de751c7e9078168344ee0d5a2", 106 | "0x70c7e7d75f49ceaa428c5636937eeaa0ef34f93962f2b70099fd285655af4aad", 107 | "0x66513043aeccb85cafec14d6fc3e2f27c6d29d352b735864b9ebcc52670f3e2e", 108 | "0x5e26a0e4ee5f76b890a5de15d4c45fb17fdd2aa37e9e0867104ee9e786c49f10", 109 | "0x65bc3d1fb869b589f52c4e1bf5484ec480c25958397bc31429af197dbfeaa287", 110 | "0x38a317708f64626f1b64ac8ce149a1e5a08d36aba61e0e793819f78dfcda2526", 111 | "0x27f1cc5a19b6e6da66d2a48f715126ece4ab7256957f8fa4cdaa7944db3ddce9", 112 | "0x3cbe401ba6b3b617ab75e5c1e15d96ac8157c15d9736d0e5a2d3c2f40eb58391", 113 | "0x4e2f22786cef17113d082e1068d87843da64fc2fbb682425d24b01cf05c84883", 114 | "0x0734dee726c833ef5a7d222faf0411e27f062151108ee761fb9a99befb834774", 115 | "0x087cfbf13828f5c40e2765f068b100a01fd8899fda981eceb719efa677486d82", 116 | "0x39e16678e42fd8c89ea1eba46d5d9b8765de9b288e02c0a30e06350479417925", 117 | "0x2480cb74e843d4c6f99dce06595cdcf8344cde223d30cb76642f1421aaa7e9c3", 118 | "0x47139137faff4a90b0f14d2ab932ac5b6c26532f492939f2a4d4b4a0b04d9ff4", 119 | "0x1d81696f2ef9a91bdc490a4fa4e2225907be1a98c8a71113e7a726dcf04464f0", 120 | "0x5537d790a77400bd245bf05c4fbf1161383701e457dd568dcdb59201018d0e5c", 121 | "0x3331a6396b7bd45222920053345fbde2da5d7c29347e0d42346972405e8ff290", 122 | "0x217089a1e35c632aef695b8cab9c22f178516c6a5fbad80875a4f829c8f928a7", 123 | "0x29777687c8aca30c56b2d393efd12d8c9a3b731759003375f04cd151d4a6540e", 124 | "0x50b68476d35acc7031d1b0eda405f230d2fcf53c74c3ca62ff44747588a5e081", 125 | "0x0e22ce3c35764329214c2ca1458ee18f0df601f1713a274a9a57141793614eef", 126 | "0x63ef3fe6a75d27936720e20a2a38b5d7f792c865b4ce0d579163b90be12d2370", 127 | "0x48ccb2904453dc8108beeab4de49615a55db917a1ecfb0ce334875c7927492aa", 128 | "0x346e73bf565e07edc27067f48219ab9f1dc7107086c3f9788ad3c7a6ca03e0b5", 129 | "0x28df5e659cc51ca86ef139daf9fd652bc0f609d833bfe849ff3ac85d4d48cf2b", 130 | "0x54a8ad58b0b288c26597688cd2e8abd09f74955ae6b67d2ce553703e43246a83", 131 | "0x0b0aa366363e65d12539e1127958758bf9c00c0c5d539ff5bcc030dc5712aa77", 132 | "0x70d1985b3bd32ceef9e4e8ac27e2cf8171813cbf5313c65502e24e7ce1ecd81a", 133 | "0x4b89156b992ec0dbba578dfd096103ab7a9b5d0e4a72fba97363025c4a9c215b", 134 | "0x172348634ee8f5686c5c98993acae02e3503ba3c28635139d55e5944634946f3", 135 | "0x05d8c0bd1d6b44c20d729b16d8def43818defc73af1098788d6c3c857226c058", 136 | "0x2139a955deb8971ae1c356242418d2445e74f66a54b9d610b49da9261af9cdd8", 137 | "0x086d467cceb8adf78d9d8b3aec6d09b22b73464da18d8d644685812099062453", 138 | "0x6b29e022f1cb486ffc36e55524426fece480e67f701bd89c070c9fa08bd27c99", 139 | "0x5abd415ec94243ea0c2f3bec670ddaa4bb175c9af0ccec15ebe30bbffe344203", 140 | "0x2cdb1742e922442e43a278c567f9030db393d5b41d065ffaf128b7275179e063", 141 | "0x4f941f1e20771396d975295325bbcefa5ca08f68defa3ebf27971b4294330222", 142 | "0x3792834ae3bca5489d3fd4b1efc7ba8d31e440c8e612f2ecc1033603c9b87c92", 143 | ]; 144 | pub const MDS_ENTRIES: &[&[&str]] = &[ 145 | &[ 146 | "0x27aad1d6257dba5efd1f4bf6bee322e87ed9af61c9a326d63fe6dc9308965a4f", 147 | "0x4d1adb9b608117da79705b82c58ba43939d5657fdbe1b31a7bf10af81642e8a8", 148 | "0x4e475db098ccf68af42217e80ce6e7f1b6ce378d5bde84436984e51b3fcd3e75", 149 | ], 150 | &[ 151 | "0x69601ef67b48f524bf34e31d6bde31d298a09f2162861f40a228d28b800a4655", 152 | "0x6bed58e1b31a50cf781ebfb88d2870a59c8c19070e7315895fd715962d14e3ed", 153 | "0x4f10d74b473c38559fa54220a330e67feecbfd659fb01c36f7f6ae6c174db30f", 154 | ], 155 | &[ 156 | "0x0f72c96fcd12b35fde687616a43eb5c994177e03095d01412823d3cd7119a4c1", 157 | "0x0a581aa60aba4333b2507f9c6fc25eb6bda21197b94ae9b8735d387ddf6164db", 158 | "0x71c0e933ccd2a5cb22e04696843fa241c0f94ff6162abea876895575fcb92b4b", 159 | ], 160 | ]; 161 | -------------------------------------------------------------------------------- /arkworks-utils/src/poseidon_params/bn254_x17_3.rs: -------------------------------------------------------------------------------- 1 | pub const FULL_ROUNDS: u8 = 8; 2 | pub const PARTIAL_ROUNDS: u8 = 57; 3 | pub const WIDTH: u8 = 3; 4 | pub const EXPONENTIATION: i8 = 17; 5 | 6 | pub const ROUND_CONSTS: &[&str] = &[ 7 | "0x1b3076f41cbcf5e9fa4b78634027ea500524cba9bbbad22fa1c4b7cc19aa66c3", 8 | "0x2bf1bc122783fa0c18aded20b5f1bd9aaefd0d87b6a8ea8fad2bddf367cc083d", 9 | "0x2f6f368166d3e953002ccc2e0c0e61663fdbb0034bb97b51ea95a935f0a9d49b", 10 | "0x25686dd23dc2d13b1f5495c9766ff0b529958dfa7568e1dbf9ba1a72d5e8207f", 11 | "0x10bda68ef40806e06c7a5a337200f7bb0780e78726fb3e656b40cb3eeadd2234", 12 | "0x28d2c5710e7bf5f003c277f1c6dd77e9be9368e01312c6d8c0c5b44194729db6", 13 | "0x2d595d8bfea5799caacdccf6a679d758999ce723fb5031e5632535adedf9fcb0", 14 | "0x298b70c75b803c70d32fbf16b6270fe96fca63b71f2458fe3752631e4b3283a7", 15 | "0x215f35ff3c6092ccd587a1c7e0f76cc058d4c1215c0709145c0df5fddbf610d1", 16 | "0x1f95bb518cee738e8ba1c5bef5ee4245c335e80d8066529f483d842bb8724108", 17 | "0x014e086a0e26de2206c607c19c294d9a4f1271642ec3e6fa25d75b34d3edd896", 18 | "0x1bc43ff9bc4dada561a29a272522b5ce78a607b27823b36702fa49b2caf0737d", 19 | "0x0feb0ad8ec3390116eb8ec87c2f8db1b8de77de5f0ceaa048af31846737c704b", 20 | "0x297861c63fc1006e29cb4453c0f52816daba75b697f7506a505b741e3c1012d9", 21 | "0x1a77213275c2433f16588a5802e35e34c66e36f5a55599fe7f306e05bf6031c8", 22 | "0x1db5a0c8a1fad3fca0edf3ced0caf927725633d2a7e004d3c2e0d911631bb597", 23 | "0x2ed8c931f260729c27badbfac10ffac282a932de62374bd3ac9678496764e5a4", 24 | "0x0ec01e6492f3d1016e906dd15a671c24d00a962e32c915065ca42533a36a8eb1", 25 | "0x1d5d981cc72a322e7684d9799600c4b938ae611b85ccc0359db9d50a14443edf", 26 | "0x1b4bf8681db9becdcb407038189624cbe13e3a1c9e730d5973bd01bc2e0b0b30", 27 | "0x2d4e57bda01ba34988e59232a99997e61d9079d0f7e93579a19432e90b527366", 28 | "0x242f43b7b5c2a7efe2457d534a82266de37f7d07b8bb558eab4596edb712e804", 29 | "0x15f4cf135455a6b6d08be9090458b92b6906fb109309679e10da9b895f76b0a1", 30 | "0x1c87f41b43d145318d4691e949b5251e608775a94f5955a8bc9bbf28087b72fd", 31 | "0x2ff9a5cde190b4e0e9c118daf823d0296b5b733974a42479d4f1208a52fe0814", 32 | "0x2462bf4ca426f9321111c199599054179995a6b73ce156035c59a16bd70bf2f7", 33 | "0x2398a82cba8e0cea9bbf22967159ad1144505be8799bb7a9b598fd8b1d2eb63e", 34 | "0x0ae80bd7e2cc3a57f9cedfc234e544c8098e2a22eab3b41befaf9ae1f45fabca", 35 | "0x015506a250a1fb6f5fc65a3386f33a93dc53b26aa4f495fe907bb37d802c7b5f", 36 | "0x16e741399442b2d58927d2594bb7e0d5a983a1eeea8dadb2fd8b93aeeec26655", 37 | "0x1bd3b94b87302d11a3d4d04f767a73790d68b73248c2e571c4d6347e39ca6917", 38 | "0x1a010f2e472e644cf4e0eeb7c18ecce574ec7820fbef669c326d52e1b097e272", 39 | "0x0797cb1c81f29d9d3f0884f643aa4233165186535cba0c2197afc75fe25ceef2", 40 | "0x17a8be97d599f43ffefc64559d3f4e14fab35ddd80b5b60c88cddccc9bb80e4d", 41 | "0x0dc0c75325ff35a54ca0979107cfbd05008b1811e5dbd13dda372576377c37cb", 42 | "0x07933bbb92bc777e0857ed9f4571a9af14cbb751d98b434c8eb41f837af0471c", 43 | "0x0abfdd844e379184e9941e370de6992f0dffd70b9fb6ba868972791c47390a38", 44 | "0x0e188bc2aac54a48e42e94ac535af5c68df6fa8ce64bf43dfd6b20b3f5a1f989", 45 | "0x242052180b3a9a1107743b627a15edc956c211680c004ef8812df8bc65d37da6", 46 | "0x0e9bd8d7e31cfc09d362c27017555ee4cb6536b8f664663afc5be308aaa55aa2", 47 | "0x0907a05e96848e94ba98195f0834606aea8df71ae86be5261959dc41779bb0cc", 48 | "0x27137bccb6552c33fafdfe103a856564a412b50af49d6f512ccc3cbd79da7716", 49 | "0x0864f9061ebb55440d5c877aaf4d36d3952d897e8f4581e01e1a4b75a5fb7b57", 50 | "0x1951ec61a3c2085511849a92fe479185356cb5921b2807dc5c822fa58e0e179a", 51 | "0x0e5207ab6856d389c917134b647a8d4a85731614c5e319155ae2b3ab91fdf5af", 52 | "0x15349491fa137b868541bcf10c3fe6f6ba2d3e238ca27bfcd044047811dfe388", 53 | "0x096b26a94ce9af3e87871606f27e3b767f8f46bd98ff4d7e454c1ba5fb49c9f3", 54 | "0x10047b0649fba4f0cab2c289fb2eb17fd4dc63f2ffbaf9a3cd441fe753157815", 55 | "0x0a516d7e68946f915be287d8d7000923e27a09d49198108a5636fc6ecd82d416", 56 | "0x2ead013caba384351de47091b8aaad12764debc85c368ff98de89f75cf558482", 57 | "0x1a258e974fc498e766987463fbd111eea24cb8ea8a232de8079ee49ab534264e", 58 | "0x1f392db78f8adfd70fea8d88c3e7388d062999b0d8f19c0f2b4c85d2196a7ea9", 59 | "0x0ff2cdd0237410ff183ceccaff4f48446d41a712b7c4babdd4a09c79bce40322", 60 | "0x1954994cd2ab37da04bb80325c4e16652ed79e9c84879ba1204eba55f66bc4b1", 61 | "0x091dace3590396c4bbc0bc75c15dbb9e379f8cb450f340673efc0353b12cc42d", 62 | "0x2a1d4c5e20d6567cfdb428365faa28177d900b268d71eeffa0e852a32e500de5", 63 | "0x08f7df5ae38ec0a864203d5ce74aca86cd6273e5d045cb98e2908004ed2183e5", 64 | "0x15ee3fc251e3afdb1d87fbdf5297088064b89959e47c96b451644082129a0a63", 65 | "0x17e8b55b6b221947a0e89a2df49533190cf71c906fed16f1d85aaa65fbcb5345", 66 | "0x045a0001f5ca1008c1297c8c845f438819a3e1de12a4db6601d364fefce08466", 67 | "0x21ffc6a3475e5a77759c45f9e15f5a140cb6d23d103951b951467acefdcbe48a", 68 | "0x1cb90d3f9df7e3838e40c7b8776f692b10ddc169e7d29d5485f1c478ff3e9b74", 69 | "0x1274b0e74b22eedbd0b3edf57270525c14c4dc13b3098b0bbf089953b8f2b4b8", 70 | "0x0f919a05a6d6762f3ca0b3042148f0b4501751ec146cda108bc6a4937dcd7a20", 71 | "0x278d8a78a647db6b698ba4740533fffe59412591f8f9eb295ea50e08ce38bf08", 72 | "0x211320e94a851bf7c2660648a3bba16f822aef5118561805427651995f8db3f4", 73 | "0x1950aa5510490993c0a5470f4d300223c26e0abf8ec3bab547a6fb1668319afe", 74 | "0x12612b4f58eb767dab7223de0b53106e5f78f60ae5854c862b14f834c7e34e2d", 75 | "0x0ccf8cdab25538f28cf9e2ab2aa54043b40365a5dfce0dc56940118a175a4936", 76 | "0x225d91a14448a93785457903a1444e2c0bca0ae3bb3490b4a1f448bbde88321a", 77 | "0x17f866a83abbfb3f5b20a0fb40861b669fdeaac1673ccf7233bff2726ef07c12", 78 | "0x274ff4db91a135b7ba61d39ddd2734fac38587d980992415c29dda232958e785", 79 | "0x2c7003822597c33cdb0b1c6fab8661f76ca8ed03be676a582572d773a3433dfc", 80 | "0x001cd295eabaac4a64c57e07364caf03279e25b58805d1590e493e79b2dd1ae4", 81 | "0x09d6d81f21776bbef325f9bae6f9f417059bdaeef40c3d3de755203370493efc", 82 | "0x09136a76223adbe2bac5105bdbe30e0a4aad7f84b30226712572adac387199d9", 83 | "0x1cfcd0dee899234b8829088c6a46c2892050a436fe261a9fe4180d0e8719f94b", 84 | "0x1f45484b7e5d4bd51a2ddef8d7bbfb1d3f4aa19728233025eb422837af8d9072", 85 | "0x1c4abe3b58f679db34b38c58a4df389ed7e981bce43df9e53099bec757963a57", 86 | "0x06982e0f4b537c75a436b321de06f9ab347519500a38a5b22ea7554a8f56e0f8", 87 | "0x07046365d522cc5022a72f52bf0dcacca143e90f54cd1b0caee3a5b19d2246f4", 88 | "0x01efcc089f07fe8a25fde5c328678633c9ec23cdaf554d21b17a7f11ffd13cb7", 89 | "0x14bc004b83a71020e8b683b6e845db1073bcf25b0d7203f43d8a7fff2b5fae77", 90 | "0x2ddd92756d1ca22599283cb365f50d429f4737d258a4241f80d9babae4730b4c", 91 | "0x17ece7004ca56d33c9c5968ef9e150da329b8882987c323d81093d6ac0824b2e", 92 | "0x281bbf1c45bff63378c0457dc44fb069d8c237e27995dc61846d46cebbb18238", 93 | "0x1a00b62874d4619e211be98505ef9ef764b21f9e0c63d95ae5baa5bd9956e1af", 94 | "0x20ad921df9e684a135efa3f1391f81c3dbbde67b7ba74892540eabed4b8a18e5", 95 | "0x06bbbd8057fe0e147cf1cbbd40251f0bf5987e7cd67f69a512b66e3070173ffc", 96 | "0x1e1c12cb34e808e17fb41da0a333d721a674864cc579b7ea0b38cadcadcaa680", 97 | "0x2b883aff71e7de12f8cbd77e365315fce4cef16f39e0ba936dd486fc93143d82", 98 | "0x2b0c1f712a5d20afc47b55229943b6e18624294f5ecd61c9a63fa5460a7ca60b", 99 | "0x20318affc0894f26029dc515a9481d42cae1bdceae78ba8fd3148868dedcf5fb", 100 | "0x0c6e1b2ac252339f0df200a40e58be6a84ad16eed290688a93ccbd89f4218170", 101 | "0x2006de7a6d053e39653625c6b32429a189794bf217b16ff2157ea40ee9795f4e", 102 | "0x13eb3541962c2a5408302a4a7ef4ae5b42e1aeb65b663f5c2b62bd13c7cc214e", 103 | "0x180631350852e5a0c04efd2898d963bc5b3ad352ec98116840e7898f259a9713", 104 | "0x1e93c8feacc032df27f42338fc2764e60cf84ff4e24ed1adf6509b2989eb411e", 105 | "0x07911273cff73e90c9c63fe23d05a7fde3fd086ccff068c4fb42bb2a8ce4304d", 106 | "0x24133be73ee303f6ded5cec002ff07c22534ec770055b03dff7ce601691f49b1", 107 | "0x120a1a812ebcd499ff86344575d580c545f2a87d6abe23f0576e66ea3daee174", 108 | "0x0b91597db31d928492d432dfc29817b5bbb8255cc43f3ddb27dd8bcd4bfb50b8", 109 | "0x140715365175ebd2328718b979ac6d994e304dc26a0a57484abf61a72f4b856f", 110 | "0x2a1fc89fe556f8675356da275941577f76c3743f45ea6381c437bfd2c072d1c1", 111 | "0x04f981ebe367ab4076112d77fbafb9e1467738b9300bbb7526de0a526c81288c", 112 | "0x090294318e3ce0b78e5afa9a0dce6b35e83169e07c4416239a3b45f89e672711", 113 | "0x2c242a8b017fe4ca2b5eba61e1da12b5739e01681409e697331c0692c0906031", 114 | "0x2dbe33685c5ac43222a9d6ba08183a3866938c8935a8f2e848441a6665f8c9a0", 115 | "0x076a8f44648ee1b4cf58ca4aa24a9a81c86f729a1fbae07effc0b7301fbcbe84", 116 | "0x0923e6801cdbb68c1762040ab0745b7e0cc0a0775d6c9df01b90e299174fa03c", 117 | "0x28187baae9864f27813aeb073775f9ed0752167e598612a2e21652da9e1e9cd7", 118 | "0x0041d72e6ecaf8313949f8ad7b5f370ffa403abff55cfd285be93083a810d90a", 119 | "0x0453618b764c28db39028e848007d73ec0262a5a2b38033238b1e27d6468cdb0", 120 | "0x142da4aab19cf148479876d07ef12d2105e504f2980b8fa21a0869344e6b167a", 121 | "0x157ac3ce8fff96af9216dd67cc31d93c10fc38437398a57c22997aad11851d46", 122 | "0x076d9c8634610797282a670a965cf9c72cc3200c7da2f1fcdbd375fa07e2fab4", 123 | "0x2002548afde4ddb43cdfc34b7ac0e0c6e35863bc649b161f52244eba8b792973", 124 | "0x04728521ee32f7da39fdd4fae3160234e81d682160a89a34a76273bff47136f6", 125 | "0x09d2d5ad962d3faaf1735bcef4878aca2cb3e9d667ea366a3c97f1e4e38fd07b", 126 | "0x069e6ab1f581cfa30207b88ae57c3b14e36119ffcd81db94ea295fab5e81b174", 127 | "0x2a0343cb81ef3a8b39a96185d2289c9cf36cda665bb76a241282b35564e51add", 128 | "0x0336c68f9dab0d529e632f6bc7a20702e81d7c2285b73541ad6536e5fa1ee91f", 129 | "0x196f84b4b83f43f417a720c73b1afc4351085da4426fe6ca79b44e0beb6a065b", 130 | ]; 131 | 132 | pub const MDS_ENTRIES: &[&[&str]] = &[ 133 | &[ 134 | "0x11092c76ff96d6a5a24f9bb3b960f3d860d35e0b95a0f94fd6ffa3784ece5ce4", 135 | "0x19e8e51059fbe675b15135eb37fb1bd7cfe8ecb5720cfcf215d72274a16b9eae", 136 | "0x2850794e401ab8618711e58af8befe1a486515e401a6df5d89c306f820c91f20", 137 | ], 138 | &[ 139 | "0x2b188f45b21764e43e4ace9ebf0cddb859e0e2a00c2b51b1c4471e73c6648d35", 140 | "0x01f574af43d21ea5ed52561538aa36cdeb8436589314368262f42a988d83ad5f", 141 | "0x1190ec00645944c68d1a3134f5f0fdedb38130950f55b996a2b2b70d84809b60", 142 | ], 143 | &[ 144 | "0x27be16a50d71f7009fd08e84936e1156ac558a467fb595281bb27530edbd4416", 145 | "0x0a2dbdac4f4e49c36bfc08c9b3f6b3f2fc3d1aa3601a2ae1dbd64c46ae5491d2", 146 | "0x160f3229d7a28e97795fb81af3858237d7992950dac77754b465d5bc40ad17cc", 147 | ], 148 | ]; 149 | -------------------------------------------------------------------------------- /arkworks-utils/src/poseidon_params/bn254_x5_2.rs: -------------------------------------------------------------------------------- 1 | pub const FULL_ROUNDS: u8 = 8; 2 | pub const PARTIAL_ROUNDS: u8 = 56; 3 | pub const WIDTH: u8 = 2; 4 | pub const EXPONENTIATION: i8 = 5; 5 | 6 | pub const ROUND_CONSTS: &[&str] = &[ 7 | "0x09c46e9ec68e9bd4fe1faaba294cba38a71aa177534cdd1b6c7dc0dbd0abd7a7", 8 | "0x0c0356530896eec42a97ed937f3135cfc5142b3ae405b8343c1d83ffa604cb81", 9 | "0x1e28a1d935698ad1142e51182bb54cf4a00ea5aabd6268bd317ea977cc154a30", 10 | "0x27af2d831a9d2748080965db30e298e40e5757c3e008db964cf9e2b12b91251f", 11 | "0x1e6f11ce60fc8f513a6a3cfe16ae175a41291462f214cd0879aaf43545b74e03", 12 | "0x2a67384d3bbd5e438541819cb681f0be04462ed14c3613d8f719206268d142d3", 13 | "0x0b66fdf356093a611609f8e12fbfecf0b985e381f025188936408f5d5c9f45d0", 14 | "0x012ee3ec1e78d470830c61093c2ade370b26c83cc5cebeeddaa6852dbdb09e21", 15 | "0x0252ba5f6760bfbdfd88f67f8175e3fd6cd1c431b099b6bb2d108e7b445bb1b9", 16 | "0x179474cceca5ff676c6bec3cef54296354391a8935ff71d6ef5aeaad7ca932f1", 17 | "0x2c24261379a51bfa9228ff4a503fd4ed9c1f974a264969b37e1a2589bbed2b91", 18 | "0x1cc1d7b62692e63eac2f288bd0695b43c2f63f5001fc0fc553e66c0551801b05", 19 | "0x255059301aada98bb2ed55f852979e9600784dbf17fbacd05d9eff5fd9c91b56", 20 | "0x28437be3ac1cb2e479e1f5c0eccd32b3aea24234970a8193b11c29ce7e59efd9", 21 | "0x28216a442f2e1f711ca4fa6b53766eb118548da8fb4f78d4338762c37f5f2043", 22 | "0x2c1f47cd17fa5adf1f39f4e7056dd03feee1efce03094581131f2377323482c9", 23 | "0x07abad02b7a5ebc48632bcc9356ceb7dd9dafca276638a63646b8566a621afc9", 24 | "0x0230264601ffdf29275b33ffaab51dfe9429f90880a69cd137da0c4d15f96c3c", 25 | "0x1bc973054e51d905a0f168656497ca40a864414557ee289e717e5d66899aa0a9", 26 | "0x2e1c22f964435008206c3157e86341edd249aff5c2d8421f2a6b22288f0a67fc", 27 | "0x1224f38df67c5378121c1d5f461bbc509e8ea1598e46c9f7a70452bc2bba86b8", 28 | "0x02e4e69d8ba59e519280b4bd9ed0068fd7bfe8cd9dfeda1969d2989186cde20e", 29 | "0x1f1eccc34aaba0137f5df81fc04ff3ee4f19ee364e653f076d47e9735d98018e", 30 | "0x1672ad3d709a353974266c3039a9a7311424448032cd1819eacb8a4d4284f582", 31 | "0x283e3fdc2c6e420c56f44af5192b4ae9cda6961f284d24991d2ed602df8c8fc7", 32 | "0x1c2a3d120c550ecfd0db0957170fa013683751f8fdff59d6614fbd69ff394bcc", 33 | "0x216f84877aac6172f7897a7323456efe143a9a43773ea6f296cb6b8177653fbd", 34 | "0x2c0d272becf2a75764ba7e8e3e28d12bceaa47ea61ca59a411a1f51552f94788", 35 | "0x16e34299865c0e28484ee7a74c454e9f170a5480abe0508fcb4a6c3d89546f43", 36 | "0x175ceba599e96f5b375a232a6fb9cc71772047765802290f48cd939755488fc5", 37 | "0x0c7594440dc48c16fead9e1758b028066aa410bfbc354f54d8c5ffbb44a1ee32", 38 | "0x1a3c29bc39f21bb5c466db7d7eb6fd8f760e20013ccf912c92479882d919fd8d", 39 | "0x0ccfdd906f3426e5c0986ea049b253400855d349074f5a6695c8eeabcd22e68f", 40 | "0x14f6bc81d9f186f62bdb475ce6c9411866a7a8a3fd065b3ce0e699b67dd9e796", 41 | "0x0962b82789fb3d129702ca70b2f6c5aacc099810c9c495c888edeb7386b97052", 42 | "0x1a880af7074d18b3bf20c79de25127bc13284ab01ef02575afef0c8f6a31a86d", 43 | "0x10cba18419a6a332cd5e77f0211c154b20af2924fc20ff3f4c3012bb7ae9311b", 44 | "0x057e62a9a8f89b3ebdc76ba63a9eaca8fa27b7319cae3406756a2849f302f10d", 45 | "0x287c971de91dc0abd44adf5384b4988cb961303bbf65cff5afa0413b44280cee", 46 | "0x21df3388af1687bbb3bca9da0cca908f1e562bc46d4aba4e6f7f7960e306891d", 47 | "0x1be5c887d25bce703e25cc974d0934cd789df8f70b498fd83eff8b560e1682b3", 48 | "0x268da36f76e568fb68117175cea2cd0dd2cb5d42fda5acea48d59c2706a0d5c1", 49 | "0x0e17ab091f6eae50c609beaf5510ececc5d8bb74135ebd05bd06460cc26a5ed6", 50 | "0x04d727e728ffa0a67aee535ab074a43091ef62d8cf83d270040f5caa1f62af40", 51 | "0x0ddbd7bf9c29341581b549762bc022ed33702ac10f1bfd862b15417d7e39ca6e", 52 | "0x2790eb3351621752768162e82989c6c234f5b0d1d3af9b588a29c49c8789654b", 53 | "0x1e457c601a63b73e4471950193d8a570395f3d9ab8b2fd0984b764206142f9e9", 54 | "0x21ae64301dca9625638d6ab2bbe7135ffa90ecd0c43ff91fc4c686fc46e091b0", 55 | "0x0379f63c8ce3468d4da293166f494928854be9e3432e09555858534eed8d350b", 56 | "0x002d56420359d0266a744a080809e054ca0e4921a46686ac8c9f58a324c35049", 57 | "0x123158e5965b5d9b1d68b3cd32e10bbeda8d62459e21f4090fc2c5af963515a6", 58 | "0x0be29fc40847a941661d14bbf6cbe0420fbb2b6f52836d4e60c80eb49cad9ec1", 59 | "0x1ac96991dec2bb0557716142015a453c36db9d859cad5f9a233802f24fdf4c1a", 60 | "0x1596443f763dbcc25f4964fc61d23b3e5e12c9fa97f18a9251ca3355bcb0627e", 61 | "0x12e0bcd3654bdfa76b2861d4ec3aeae0f1857d9f17e715aed6d049eae3ba3212", 62 | "0x0fc92b4f1bbea82b9ea73d4af9af2a50ceabac7f37154b1904e6c76c7cf964ba", 63 | "0x1f9c0b1610446442d6f2e592a8013f40b14f7c7722236f4f9c7e965233872762", 64 | "0x0ebd74244ae72675f8cde06157a782f4050d914da38b4c058d159f643dbbf4d3", 65 | "0x2cb7f0ed39e16e9f69a9fafd4ab951c03b0671e97346ee397a839839dccfc6d1", 66 | "0x1a9d6e2ecff022cc5605443ee41bab20ce761d0514ce526690c72bca7352d9bf", 67 | "0x2a115439607f335a5ea83c3bc44a9331d0c13326a9a7ba3087da182d648ec72f", 68 | "0x23f9b6529b5d040d15b8fa7aee3e3410e738b56305cd44f29535c115c5a4c060", 69 | "0x05872c16db0f72a2249ac6ba484bb9c3a3ce97c16d58b68b260eb939f0e6e8a7", 70 | "0x1300bdee08bb7824ca20fb80118075f40219b6151d55b5c52b624a7cdeddf6a7", 71 | "0x19b9b63d2f108e17e63817863a8f6c288d7ad29916d98cb1072e4e7b7d52b376", 72 | "0x015bee1357e3c015b5bda237668522f613d1c88726b5ec4224a20128481b4f7f", 73 | "0x2953736e94bb6b9f1b9707a4f1615e4efe1e1ce4bab218cbea92c785b128ffd1", 74 | "0x0b069353ba091618862f806180c0385f851b98d372b45f544ce7266ed6608dfc", 75 | "0x304f74d461ccc13115e4e0bcfb93817e55aeb7eb9306b64e4f588ac97d81f429", 76 | "0x15bbf146ce9bca09e8a33f5e77dfe4f5aad2a164a4617a4cb8ee5415cde913fc", 77 | "0x0ab4dfe0c2742cde44901031487964ed9b8f4b850405c10ca9ff23859572c8c6", 78 | "0x0e32db320a044e3197f45f7649a19675ef5eedfea546dea9251de39f9639779a", 79 | "0x0a1756aa1f378ca4b27635a78b6888e66797733a82774896a3078efa516da016", 80 | "0x044c4a33b10f693447fd17177f952ef895e61d328f85efa94254d6a2a25d93ef", 81 | "0x2ed3611b725b8a70be655b537f66f700fe0879d79a496891d37b07b5466c4b8b", 82 | "0x1f9ba4e8bab7ce42c8ecc3d722aa2e0eadfdeb9cfdd347b5d8339ea7120858aa", 83 | "0x1b233043052e8c288f7ee907a84e518aa38e82ac4502066db74056f865c5d3da", 84 | "0x2431e1cc164bb8d074031ab72bd55b4c902053bfc0f14db0ca2f97b020875954", 85 | "0x082f934c91f5aac330cd6953a0a7db45a13e322097583319a791f273965801fd", 86 | "0x2b9a0a223e7538b0a34be074315542a3c77245e2ae7cbe999ad6bb930c48997c", 87 | "0x0e1cd91edd2cfa2cceb85483b887a9be8164163e75a8a00eb0b589cc70214e7d", 88 | "0x2e1eac0f2bfdfd63c951f61477e3698999774f19854d00f588d324601cebe2f9", 89 | "0x0cbfa95f37fb74060c76158e769d6d157345784d8efdb33c23d748115b500b83", 90 | "0x08f05b3be923ed44d65ad49d8a61e9a676d991e3a77513d9980c232dfa4a4f84", 91 | "0x22719e2a070bcd0852bf8e21984d0443e7284925dc0758a325a2dd510c047ef6", 92 | "0x041f596a9ee1cb2bc060f7fcc3a1ab4c7bdbf036119982c0f41f62b2f26830c0", 93 | "0x233fd35de1be520a87628eb06f6b1d4c021be1c2d0dc464a19fcdd0986b10f89", 94 | "0x0524b46d1aa87a5e4325e0a423ebc810d31e078aa1b4707eefcb453c61c9c267", 95 | "0x2c34f424c81e5716ce47fcac894b85824227bb954b0f3199cc4486237c515211", 96 | "0x0b5f2a4b63387819207effc2b5541fb72dd2025b5457cc97f33010327de4915e", 97 | "0x22207856082ccc54c5b72fe439d2cfd6c17435d2f57af6ceaefac41fe05c659f", 98 | "0x24d57a8bf5da63fe4e24159b7f8950b5cdfb210194caf79f27854048ce2c8171", 99 | "0x0afab181fdd5e0583b371d75bd693f98374ad7097bb01a8573919bb23b79396e", 100 | "0x2dba9b108f208772998a52efac7cbd5676c0057194c16c0bf16290d62b1128ee", 101 | "0x26349b66edb8b16f56f881c788f53f83cbb83de0bd592b255aff13e6bce420b3", 102 | "0x25af7ce0e5e10357685e95f92339753ad81a56d28ecc193b235288a3e6f137db", 103 | "0x25b4ce7bd2294390c094d6a55edd68b970eed7aae88b2bff1f7c0187fe35011f", 104 | "0x22c543f10f6c89ec387e53f1908a88e5de9cef28ebdf30b18cb9d54c1e02b631", 105 | "0x0236f93e7789c4724fc7908a9f191e1e425e906a919d7a34df668e74882f87a9", 106 | "0x29350b401166ca010e7d27e37d05da99652bdae114eb01659cb497af980c4b52", 107 | "0x0eed787d65820d3f6bd31bbab547f75a65edb75d844ebb89ee1260916652363f", 108 | "0x07cc1170f13b46f2036a753f520b3291fdcd0e99bd94297d1906f656f4de6fad", 109 | "0x22b939233b1d7205f49bcf613a3d30b1908786d7f9f5d10c2059435689e8acea", 110 | "0x01451762a0aab81c8aad1dc8bc33e870740f083a5aa85438add650ace60ae5a6", 111 | "0x23506bb5d8727d4461fabf1025d46d1fe32eaa61dec7da57e704fec0892fce89", 112 | "0x2e484c44e838aea0bac06ae3f71bdd092a3709531e1efea97f8bd68907355522", 113 | "0x0f4bc7d07ebafd64379e78c50bd2e42baf4a594545cedc2545418da26835b54c", 114 | "0x1f4d3c8f6583e9e5fa76637862faaee851582388725df460e620996d50d8e74e", 115 | "0x093514e0c70711f82660d07be0e4a988fae02abc7b681d9153eb9bcb48fe7389", 116 | "0x1adab0c8e2b3bad346699a2b5f3bc03643ee83ece47228f24a58e0a347e153d8", 117 | "0x1672b1726057d99dd14709ebb474641a378c1b94b8072bac1a22dbef9e80dad2", 118 | "0x1dfd53d4576af2e38f44f53fdcab468cc5d8e2fae0acc4ee30d47b239b479c14", 119 | "0x0c6888a10b75b0f3a70a36263a37e17fe6d77d640f6fc3debc7f207753205c60", 120 | "0x1addb933a65be77092b34a7e77d12fe8611a61e00ee6848b85091ecca9d1e508", 121 | "0x00d7540dcd268a845c10ae18d1de933cf638ff5425f0afff7935628e299d1791", 122 | "0x140c0e42687e9ead01b2827a5664ca9c26fedde4acd99db1d316939d20b82c0e", 123 | "0x2f0c3a115d4317d191ba89b8d13d1806c20a0f9b24f8c5edc091e2ae56565984", 124 | "0x0c4ee778ff7c14553006ed220cf9c81008a0cff670b22b82d8c538a1dc958c61", 125 | "0x1704f2766d46f82c3693f00440ccc3609424ed26c0acc66227c3d7485de74c69", 126 | "0x2f2d19cc3ea5d78ea7a02c1b51d244abf0769c9f8544e40239b66fe9009c3cfa", 127 | "0x1ae03853b75fcaba5053f112e2a8e8dcdd7ee6cb9cfed9c7d6c766a806fc6629", 128 | "0x0971aabf795241df51d131d0fa61aa5f3556921b2d6f014e4e41a86ddaf056d5", 129 | "0x1408c316e6014e1a91d4cf6b6e0de73eda624f8380df1c875f5c29f7bfe2f646", 130 | "0x1667f3fe2edbe850248abe42b543093b6c89f1f773ef285341691f39822ef5bd", 131 | "0x13bf7c5d0d2c4376a48b0a03557cdf915b81718409e5c133424c69576500fe37", 132 | "0x07620a6dfb0b6cec3016adf3d3533c24024b95347856b79719bc0ba743a62c2c", 133 | "0x1574c7ef0c43545f36a8ca08bdbdd8b075d2959e2f322b731675de3e1982b4d0", 134 | "0x269e4b5b7a2eb21afd567970a717ceec5bd4184571c254fdc06e03a7ff8378f0", 135 | ]; 136 | 137 | pub const MDS_ENTRIES: &[&[&str]] = &[ 138 | &[ 139 | "0x066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5", 140 | "0x2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e8", 141 | ], 142 | &[ 143 | "0x0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff9", 144 | "0x1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c8", 145 | ], 146 | ]; -------------------------------------------------------------------------------- /arkworks-utils/src/poseidon_params/bn254_x5_3_result.rs: -------------------------------------------------------------------------------- 1 | pub const RESULT: &[&str] = &[ 2 | "0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a", 3 | "0x0fca49b798923ab0239de1c9e7a4a9a2210312b6a2f616d18b5a87f9b628ae29", 4 | "0x0e7ae82e40091e63cbd4f16a6d16310b3729d4b6e138fcf54110e2867045a30c", 5 | ]; 6 | -------------------------------------------------------------------------------- /arkworks-utils/src/poseidon_params/bn254_x5_5_result.rs: -------------------------------------------------------------------------------- 1 | pub const RESULT: &[&str] = &[ 2 | "0x299c867db6c1fdd79dcefa40e4510b9837e60ebb1ce0663dbaa525df65250465", 3 | "0x1148aaef609aa338b27dafd89bb98862d8bb2b429aceac47d86206154ffe053d", 4 | "0x24febb87fed7462e23f6665ff9a0111f4044c38ee1672c1ac6b0637d34f24907", 5 | "0x0eb08f6d809668a981c186beaf6110060707059576406b248e5d9cf6e78b3d3e", 6 | "0x07748bc6877c9b82c8b98666ee9d0626ec7f5be4205f79ee8528ef1c4a376fc7", 7 | ]; 8 | -------------------------------------------------------------------------------- /arkworks-utils/src/poseidon_params/ed_on_bn254_x17_3.rs: -------------------------------------------------------------------------------- 1 | // sage generate_parameters_grain.sage 1 0 254 3 8 33 2 | // 0x60c89ce5c263405370a08b6d0302b0bab3eedb83920ee0a677297dc392126f1 3 | pub const ROUND_CONSTS: [&str; 123] = [ 4 | "0x014e086a0e26de2206c607c19c294d9a4f1271642ec3e6fa25d75b34d3edd896", 5 | "0x015506a250a1fb6f5fc65a3386f33a93dc53b26aa4f495fe907bb37d802c7b5f", 6 | "0x045a0001f5ca1008c1297c8c845f438819a3e1de12a4db6601d364fefce08466", 7 | "0x001cd295eabaac4a64c57e07364caf03279e25b58805d1590e493e79b2dd1ae4", 8 | "0x01efcc089f07fe8a25fde5c328678633c9ec23cdaf554d21b17a7f11ffd13cb7", 9 | "0x04f981ebe367ab4076112d77fbafb9e1467738b9300bbb7526de0a526c81288c", 10 | "0x0041d72e6ecaf8313949f8ad7b5f370ffa403abff55cfd285be93083a810d90a", 11 | "0x0453618b764c28db39028e848007d73ec0262a5a2b38033238b1e27d6468cdb0", 12 | "0x04728521ee32f7da39fdd4fae3160234e81d682160a89a34a76273bff47136f6", 13 | "0x0336c68f9dab0d529e632f6bc7a20702e81d7c2285b73541ad6536e5fa1ee91f", 14 | "0x01106e7cd76c36f68de5fbbf89e5aae2fdb80551cf7b41bd96524b8ed8341491", 15 | "0x04d00b6ec45cc0f116abca222ff9d71bc20be198e629a00af5bd12589e10d81e", 16 | "0x015dbb9f5d98bc2b626163e32f3dc567974e0f3d40509898ff86dc20725f5a3d", 17 | "0x001bff94b71b594b57c5890e6e2fb135c7917f175689e8f35991681561396f1f", 18 | "0x02501be69afc8a130f75690ed96104492eac825f77556b7bbdd5ee34c5c21aca", 19 | "0x0354196e45373845b6fdcfa1f6086907f28225ffdeaa6d05e35db9c83875fb01", 20 | "0x00e12a5f7536ce4aac8f96711b7a71ea52856bd00a3ccaa423dccd3404441892", 21 | "0x0386f033c3b0e0cadb465c670424bb8555bd6d082b07169009137ad387e3af48", 22 | "0x03a608df451797f8192cb934ed0e877a447cff5332bdec78dc100e61e9701254", 23 | "0x008e2c012a0ec28acfad7d62de08df74b3264d4389f50ab19400f9bd2edb3dd0", 24 | "0x03b319850f0e791bf092aebdd64d81380b13131bebfc7d42c88dde4cf3f1b5fe", 25 | "0x01473f6a0a0b85558ede1ae9e573dd65da42acfdfd45fa441f77001857efcadc", 26 | "0x0253f9cfc6c65954b5784cbf9ca270f279e949fa509f6aec5c05f73e79cfe1f4", 27 | "0x018f9a3692bb8dbd026aae9aa0f90e708bd1678d8b97af8a1a38e4a540313e11", 28 | "0x01d4c8b6642f5ad2f6902d4816f60346a7ab923b07c12d69f2bd4d6a1ddd9644", 29 | "0x04552a3f7ee5866a11309ed097e76282434c40009b10b57340267c8bcd7547a1", 30 | "0x055b4c4c76f5c628dcb6fdbd4c71a2775f9c11cc39f8f32f01dde231232f5d5a", 31 | "0x04fcaaaf0bbb9063623516beb78d42acf7e18c22afd0c0c0e33511f07b9f7c36", 32 | "0x0256b73ef289430c22fd282efa785ca9fd5ec07fb5df36d52aecea1e4806b7c0", 33 | "0x03d599a46b1dd605c843e56a18231df3eefe9b98c28dee0c0c6c2c48902264fc", 34 | "0x00443406a46d75e68bccb364619c501aad4e03b63bb3f4ca714b8f262fa5c766", 35 | "0x04bedfdef7b6e86a8f6a5de3bd5a9f52627320ecee9a98dbf26d5c23237e3e69", 36 | "0x03988c43103eef81ca9a668c43927255d507c4fbad0738323be0c5002e687475", 37 | "0x00746cd943a037cfefaa4cb058929f8ef3d47c8adc74304f0152bb31c9eafee2", 38 | "0x04d5757a6eb1cf8fbf08f7efd766533c0d4bf959ab7fefdfc1d215e50fb662f9", 39 | "0x00f4e41ed81a018045a6b8e12cf5faa236cd16ca18bd403af8476b4b7d4f316e", 40 | "0x05e94dcac1a26ce8fcc913227a3e9b0f30dc7a175d125717aad3257e527014b2", 41 | "0x05a434468f634eda0b487c370edbd1994c5c289b7f173c666a2d1eda7265e85b", 42 | "0x01b75a949a98b579935b123082f4e7a00b9cef08a4d870ec163d7076ba6f41e1", 43 | "0x02350469e5435eba49cf66c6af138d1744eea40d9b1e3cf766125b6491974807", 44 | "0x03dabb2755f07a41e5a53206c95b9e7ebf95eba33eb8bb2d827e50daa043005e", 45 | "0x0502f7b95c682e95f92a0d4b645c6a8633282929f6dd72092d25da9c377b95d2", 46 | "0x042754067c526243e4d677ef6a25dbfe3638e6bb4366edd4545c80cbae673375", 47 | "0x037124f26a36ea7be546efdbc238bfe38e71713bbbffcabb4bdc503b79e4d75e", 48 | "0x040049aeedadce23d9eeb949862cef30f971ce87820d4a05f5f6b7f2299ca0bf", 49 | "0x02d0d6f30ee69051d503cd1264573d467d668667ed214bd85a9f269b1f1c66fd", 50 | "0x0256d33893982386fce8ee10870945eab6711b23dc9bbdac1aaa670a4c6febad", 51 | "0x0119e98547ecd21942f6e720d45cfa94f11399ee469a6ea7d55a26abe89d5d3d", 52 | "0x05bc94a5e51f18f6728bc18180e14067949779cf981dc6333efc01c1e92da5d3", 53 | "0x05e6656c1fa2607befd8a913b3187072915dfd790bee8ea2b825b388f8b157f3", 54 | "0x0043ca60e08d74d85b3eda4a663199c8c3957cc5d452b53602be2ac18b6edf82", 55 | "0x04943a2e7ab2602fcaf3af431fdf61f1647f6205ce7656e866589d394961b01f", 56 | "0x050d2cafd1a8233b0f8a972fdd0a9d255a2d41c61b8a4a402579989b58421077", 57 | "0x00a27dc534e03b40b3b2c571261f5f27ca18139c4b414237710a3cdc4970a09d", 58 | "0x0290fad8b9cb750fe8824626b6d1be2ddddec6a5d7d9fd3304ed0e1d03fc37d5", 59 | "0x00a0932894c80b1032267f0e0848b6f88c4ab7b32bc7adbdf3b26b82e76d82f4", 60 | "0x04178c208f0c3d091b968312e6c53029e2f359fda52ddc1644d4c01b0eff1736", 61 | "0x04ac8af76611ad0115cf7c763de317dc2d0cad6fba4a2a507d8ca95ab9dc2285", 62 | "0x00aeb00e6717e2858d00f8c9e0ab3cc884765b688534501a491750cfa8312454", 63 | "0x03c22157504bde1577780ac27ced1bc29935875fb7b74e1ae67067e2cc419b63", 64 | "0x0431cdc05b25e9db3cf7495906dec3fa7506d10dfb0251b510b2951bedc1cc83", 65 | "0x0474a3d3dfd3ffdae081b44bf570edecb9f32fb6ea61b2748805ecef50f68f6f", 66 | "0x00bb3b9e5ca86b503681162217e6d1286c3b24e5001415de44d35e6f514b1429", 67 | "0x013c5205144c2ce1f88b763778199fffcec31df53608131e55cc5cc32ebac8f6", 68 | "0x025887031d994eccc2ad1952563442a2e94a2b32843a6d4f8f4c79f1b9df1477", 69 | "0x048f39496c8449e764980288caabc12c9892127edcae0028d10b8be63768487b", 70 | "0x02c4637bd00818f73df619223e53555396076af548e94b40cc33ede39a39f1b1", 71 | "0x0479d7c6ff2049ac4554902ff748a7f19826042af0f2736ea2515d3896d6a4d1", 72 | "0x0520809bb7a281adf77adab925c333c369f2a8e7e246230e5a78079e2788d2ca", 73 | "0x039a63613c03c1f07c07874f9853865e56ec6c2282bc65422f95ba5079fde419", 74 | "0x0591e8cf5d1a718b69c330311313bdf848b007d3aa0392fe0bfa5a6cd94535a0", 75 | "0x03cf4f8642a832962dcd1b5029743f923a10a184ee36ae66d7f9ee21858423aa", 76 | "0x054a717e9e4041d43638bc03fc42b72cd81fa1e3e52a356ef7b15883a6624188", 77 | "0x04b8b70eb2a6272d06401d4d240a497f7c739024e717fa6e2ccc41017beaa48c", 78 | "0x05c0d44645ef1a3d82f1d7fc72b8513f0278601a3156ec9d5ad2b2902d17d17d", 79 | "0x03ae1d9a0172c2bc17c26643b67c2a7d4e23beff7e79e6c69c681abf3982dd13", 80 | "0x014685aba452330b8c91fcb001c93ebc7100a0d0da75b8e84499c18c77fe6d6d", 81 | "0x02ed9846e2aec0480c03ea9e29a14d8a9a979134d549be2eed11946b563a79a4", 82 | "0x021cb9d7e26c05be16abee3f6ea7c41a7c641c1d9c3878a524d5fc079736ac5e", 83 | "0x00478b2228cbbd724a25e31136e864761b1b50054f7e35d35551ca94a94cc230", 84 | "0x02dbd89a95cdc39b4a9215b985373c27f8160662f186ae548c1c3817edeba429", 85 | "0x042c3ad26a91606c0b9fe14740588db92bc3147ee7ad583844468871ead1e4d6", 86 | "0x0269e2949c858845b6529f9a9002337a2131379feca0b3599a0002e67a058d15", 87 | "0x00d0304ed09176a0c2937b229a3554ce5ff26ee23fed7301d20970f1e747070b", 88 | "0x03ca8fdbbe8bff72bd047569518b2c3b198cf2b6b2c03054214f6b51a6090bb1", 89 | "0x02f573e6c130ff091e8ff0db4cf9ce84e5646c18bf6ebca798a1ed86427dd7e0", 90 | "0x013a84aef38438d77288ca49ee11cd30e17311b6640c405b89bb5c4a65f857ca", 91 | "0x01200c4bd29cd6996cde149248dedd832d60e51304090649a3b6c8c235cff855", 92 | "0x05f987a5ad487f1ded2be7ba927e45e62b4984df78d307a28a3ebde3e05f3790", 93 | "0x0587de656aa8a542e198790cc3c6d487fd37c89604e0590fd32c2598b9d543bb", 94 | "0x0166f9bb6409e00ac64aa4a149d47cbdd017ae2c1fa02246b54f58f88e1a2c78", 95 | "0x00c1dc093135fce3a892674e0016b9ea5a01c343567423755b4967047ff72a92", 96 | "0x031666888460eb246902d65fc8fecda442b9e18028f17778e1734d076db5c03e", 97 | "0x052cc60267651ff534fd13043664eea114ffb9c6cd45fa4d32fcb255f5c0e6f5", 98 | "0x023e4db2df37a29e6f5b3ffbff6b27b6d4d0787aae7cab9a17e7bac99f7992e3", 99 | "0x053a12ee8386b6643f8be2b8cb98dfd6a551e76434e2a0102be19693936137ba", 100 | "0x0553805099487c554d264fb2f358a5f682f5b63ddd14304be1d450d6f6a4b53b", 101 | "0x03f2910ba52718ee7d717658637088948c1e700125cedaab0105aac4b93cddfc", 102 | "0x038e6fa9507b7efa1318d9f4131a5b19d80f81d1a4e8d1b6cd71c75fef9b4841", 103 | "0x041175884c1d813a21d299a75ba435c626343911b90febc8f166042626cca198", 104 | "0x049b57ea3884e0c51732db52c72f6f4beee010b0a08903e4cda54cb8aaf3aaa7", 105 | "0x02f9bfdd2df04d7b5623b268e1aad21ca941a4a81b8e58fd2d293af1de8dd2b1", 106 | "0x04e157aeaef5b3ef414d0028d9a81d3f47716c94d821127cd8fb1cf0c9347e76", 107 | "0x0484a4a089d9401611c5bb59255f1f30eb9f67305f9baf75f42ac8b8a4360830", 108 | "0x024c36e2d80873a30314f4dfb687e7ee1a895e1b44fab6be0463f4dc71a0340b", 109 | "0x01afb935a6da3b71fe48ca74c71a3b4759d88119d24014b32bdd1405bc851714", 110 | "0x03efc676a43b034758da40d6966eb7f9fad063314c2817f28fcb5edf41aa33e2", 111 | "0x04fabd92b3541eb91247802989b3ee25a206e4101fa276c783cd04582ef8ddfd", 112 | "0x02d513fcf15b78afbf44721b88b71e7574e22c2a7089a9e1ef07012bd7b9b383", 113 | "0x001b924a795cb953ec94313d0cae5906525980a423e7190833eee38bb76f496a", 114 | "0x00be8c338931b90d26e448a1a652e9aaa8b40d5786bcca7f66cbb5c3802989f8", 115 | "0x01534841031f3a14edd199189f861a3c458bb58e8588f511724400463ea3670b", 116 | "0x00df0b0ba902b2eea5313c22a92d9af7e7fc71b08edcf2f6b9e3d04d7577e7f2", 117 | "0x02ae3290b84338003ce5933f31f954725b30e473a735dd8c598463686f04b059", 118 | "0x0168a8f7db83f0208f2fe2d699ddd32caa1c4ce2eae4837029b249eb335bb3ed", 119 | "0x0333bb1c73838c0560e62287209d695a2763f701f522d9102da15416b0e523a1", 120 | "0x0248cdf5a7863b4f81838275c3b0cd1316d06c78620250c9cc156c2434112e43", 121 | "0x05134439ef26c3e3d3c6f4de41522f1bebdc9cf504c471d6095def1fa0891860", 122 | "0x0229ce576f2123839b7f7a7019c0d9a323f50e4a8efcff8584371345b0a1f88e", 123 | "0x024b7cb66c8e411b8c317aeaa6bd0e6065262513a12941bd0db73a4797ef5fc0", 124 | "0x007aea65a6b71c112191096baf6bec9ed98afa015c970d1178a84484f1fe547e", 125 | "0x01b935821f13d6dd5caa915e1450cab0929d669a1e577a8a851097c3448e6fb0", 126 | "0x04072758d2b8ce6a58f53f513592a47415bbb09acc761ee99ab41b29d2448dce", 127 | ]; 128 | pub const MDS_ENTRIES: [[&str; 3]; 3] = [ 129 | [ 130 | "0x055d8126365f4fd884ca1f52f10f0455f88b070476c5fffde9bf2bb5ef07a394", 131 | "0x056f2e948db739e02a12d68e8eb629120afc2c63c86f6fdbb57018e68495dd24", 132 | "0x056fdea02d4751eec55aa670cecba5567a57200f8b5dfb48dfd1eae8af46eeb1", 133 | ], 134 | [ 135 | "0x03cb4a21fd13393ba31cceaa984c94833417bccd63a3e41eef0b06926dc35086", 136 | "0x02b7a624d5d58fef0b124dc7e9fde43866891e425747304778dbd36d4c2fb9c3", 137 | "0x04c08de963026bb129915750146820b2592cdae362574f3ca0a7a26502fea6fe", 138 | ], 139 | [ 140 | "0x01d346915ade64140d6ddaca825f62e99582a17373b0f7942c2b1c648f435c19", 141 | "0x05d9d163b66c50d0fb82250781120b54369471733f98ed142e5a706d91769fb8", 142 | "0x033de9bed682bf475337b9a8bd5f0538d6ca417bb55d4a5c0b93d814bd732340", 143 | ], 144 | ]; 145 | -------------------------------------------------------------------------------- /arkworks-utils/src/poseidon_params/mod.rs: -------------------------------------------------------------------------------- 1 | use super::{parse_matrix, parse_vec, Bytes, Curve, FromHexError}; 2 | 3 | pub use ark_std::vec::Vec; 4 | 5 | pub struct PoseidonData { 6 | pub mds: Vec>, 7 | pub rounds: Vec, 8 | pub full_rounds: u8, 9 | pub partial_rounds: u8, 10 | pub width: u8, 11 | pub exp: i8, 12 | } 13 | 14 | impl PoseidonData { 15 | pub fn new( 16 | mds: Vec>, 17 | rounds: Vec, 18 | full_rounds: u8, 19 | partial_rounds: u8, 20 | width: u8, 21 | exp: i8, 22 | ) -> Self { 23 | Self { 24 | mds, 25 | rounds, 26 | full_rounds, 27 | partial_rounds, 28 | exp, 29 | width, 30 | } 31 | } 32 | } 33 | 34 | pub fn setup_poseidon_params( 35 | curve: Curve, 36 | exp: i8, 37 | width: u8, 38 | ) -> Result { 39 | // Making params for poseidon in merkle tree 40 | match (curve, exp, width) { 41 | #[cfg(feature = "poseidon_bls381_x3_3")] 42 | (Curve::Bls381, 3, 3) => { 43 | #[path = "./bls381_x3_3.rs"] 44 | mod bls381_x3_3; 45 | use bls381_x3_3::{ 46 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 47 | }; 48 | get_poseidon_data( 49 | ROUND_CONSTS, 50 | MDS_ENTRIES, 51 | FULL_ROUNDS, 52 | PARTIAL_ROUNDS, 53 | WIDTH, 54 | EXPONENTIATION, 55 | ) 56 | } 57 | #[cfg(feature = "poseidon_bn254_x3_3")] 58 | (Curve::Bn254, 3, 3) => { 59 | #[path = "./bn254_x3_3.rs"] 60 | pub mod bn254_x3_3; 61 | use bn254_x3_3::{ 62 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 63 | }; 64 | get_poseidon_data( 65 | ROUND_CONSTS, 66 | MDS_ENTRIES, 67 | FULL_ROUNDS, 68 | PARTIAL_ROUNDS, 69 | WIDTH, 70 | EXPONENTIATION, 71 | ) 72 | } 73 | #[cfg(feature = "poseidon_bls381_x3_5")] 74 | (Curve::Bls381, 3, 5) => { 75 | #[path = "./bls381_x3_5.rs"] 76 | pub mod bls381_x3_5; 77 | use bls381_x3_5::{ 78 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 79 | }; 80 | get_poseidon_data( 81 | ROUND_CONSTS, 82 | MDS_ENTRIES, 83 | FULL_ROUNDS, 84 | PARTIAL_ROUNDS, 85 | WIDTH, 86 | EXPONENTIATION, 87 | ) 88 | } 89 | #[cfg(feature = "poseidon_bn254_x3_5")] 90 | (Curve::Bn254, 3, 5) => { 91 | #[path = "./bn254_x3_5.rs"] 92 | pub mod bn254_x3_5; 93 | use bn254_x3_5::{ 94 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 95 | }; 96 | get_poseidon_data( 97 | ROUND_CONSTS, 98 | MDS_ENTRIES, 99 | FULL_ROUNDS, 100 | PARTIAL_ROUNDS, 101 | WIDTH, 102 | EXPONENTIATION, 103 | ) 104 | } 105 | #[cfg(feature = "poseidon_bls381_x5_3")] 106 | (Curve::Bls381, 5, 3) => { 107 | #[path = "./bls381_x5_3.rs"] 108 | pub mod bls381_x5_3; 109 | use bls381_x5_3::{ 110 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 111 | }; 112 | get_poseidon_data( 113 | ROUND_CONSTS, 114 | MDS_ENTRIES, 115 | FULL_ROUNDS, 116 | PARTIAL_ROUNDS, 117 | WIDTH, 118 | EXPONENTIATION, 119 | ) 120 | } 121 | #[cfg(feature = "poseidon_bn254_x5_3")] 122 | (Curve::Bn254, 5, 3) => { 123 | #[path = "./bn254_x5_3.rs"] 124 | pub mod bn254_x5_3; 125 | use bn254_x5_3::{ 126 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 127 | }; 128 | get_poseidon_data( 129 | ROUND_CONSTS, 130 | MDS_ENTRIES, 131 | FULL_ROUNDS, 132 | PARTIAL_ROUNDS, 133 | WIDTH, 134 | EXPONENTIATION, 135 | ) 136 | } 137 | #[cfg(feature = "poseidon_bn254_x5_2")] 138 | (Curve::Bn254, 5, 2) => { 139 | #[path = "./bn254_x5_2.rs"] 140 | pub mod bn254_x5_2; 141 | use bn254_x5_2::{ 142 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 143 | }; 144 | get_poseidon_data( 145 | ROUND_CONSTS, 146 | MDS_ENTRIES, 147 | FULL_ROUNDS, 148 | PARTIAL_ROUNDS, 149 | WIDTH, 150 | EXPONENTIATION, 151 | ) 152 | } 153 | #[cfg(feature = "poseidon_bn254_x5_4")] 154 | (Curve::Bn254, 5, 4) => { 155 | #[path = "./bn254_x5_4.rs"] 156 | pub mod bn254_x5_4; 157 | use bn254_x5_4::{ 158 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 159 | }; 160 | get_poseidon_data( 161 | ROUND_CONSTS, 162 | MDS_ENTRIES, 163 | FULL_ROUNDS, 164 | PARTIAL_ROUNDS, 165 | WIDTH, 166 | EXPONENTIATION, 167 | ) 168 | } 169 | #[cfg(feature = "poseidon_bls381_x5_5")] 170 | (Curve::Bls381, 5, 5) => { 171 | #[path = "./bls381_x5_5.rs"] 172 | pub mod bls381_x5_5; 173 | use bls381_x5_5::{ 174 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 175 | }; 176 | get_poseidon_data( 177 | ROUND_CONSTS, 178 | MDS_ENTRIES, 179 | FULL_ROUNDS, 180 | PARTIAL_ROUNDS, 181 | WIDTH, 182 | EXPONENTIATION, 183 | ) 184 | } 185 | #[cfg(feature = "poseidon_bn254_x5_5")] 186 | (Curve::Bn254, 5, 5) => { 187 | #[path = "./bn254_x5_5.rs"] 188 | pub mod bn254_x5_5; 189 | use bn254_x5_5::{ 190 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 191 | }; 192 | get_poseidon_data( 193 | ROUND_CONSTS, 194 | MDS_ENTRIES, 195 | FULL_ROUNDS, 196 | PARTIAL_ROUNDS, 197 | WIDTH, 198 | EXPONENTIATION, 199 | ) 200 | } 201 | #[cfg(feature = "poseidon_bls381_x17_3")] 202 | (Curve::Bls381, 17, 3) => { 203 | #[path = "./bls381_x17_3.rs"] 204 | pub mod bls381_x17_3; 205 | use bls381_x17_3::{ 206 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 207 | }; 208 | get_poseidon_data( 209 | ROUND_CONSTS, 210 | MDS_ENTRIES, 211 | FULL_ROUNDS, 212 | PARTIAL_ROUNDS, 213 | WIDTH, 214 | EXPONENTIATION, 215 | ) 216 | } 217 | #[cfg(feature = "poseidon_bn254_x17_3")] 218 | (Curve::Bn254, 17, 3) => { 219 | #[path = "./bn254_x17_3.rs"] 220 | pub mod bn254_x17_3; 221 | use bn254_x17_3::{ 222 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 223 | }; 224 | get_poseidon_data( 225 | ROUND_CONSTS, 226 | MDS_ENTRIES, 227 | FULL_ROUNDS, 228 | PARTIAL_ROUNDS, 229 | WIDTH, 230 | EXPONENTIATION, 231 | ) 232 | } 233 | #[cfg(feature = "poseidon_bls381_x17_5")] 234 | (Curve::Bls381, 17, 5) => { 235 | #[path = "./bls381_x17_5.rs"] 236 | pub mod bls381_x17_5; 237 | use bls381_x17_5::{ 238 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 239 | }; 240 | get_poseidon_data( 241 | ROUND_CONSTS, 242 | MDS_ENTRIES, 243 | FULL_ROUNDS, 244 | PARTIAL_ROUNDS, 245 | WIDTH, 246 | EXPONENTIATION, 247 | ) 248 | } 249 | #[cfg(feature = "poseidon_bn254_x17_5")] 250 | (Curve::Bn254, 17, 5) => { 251 | #[path = "./bn254_x17_5.rs"] 252 | pub mod bn254_x17_5; 253 | use bn254_x17_5::{ 254 | EXPONENTIATION, FULL_ROUNDS, MDS_ENTRIES, PARTIAL_ROUNDS, ROUND_CONSTS, WIDTH, 255 | }; 256 | get_poseidon_data( 257 | ROUND_CONSTS, 258 | MDS_ENTRIES, 259 | FULL_ROUNDS, 260 | PARTIAL_ROUNDS, 261 | WIDTH, 262 | EXPONENTIATION, 263 | ) 264 | } 265 | _ => unimplemented!(), 266 | } 267 | } 268 | 269 | pub fn get_poseidon_result(curve: Curve, exp: i8, width: u8) -> Result, FromHexError> { 270 | match (curve, exp, width) { 271 | #[cfg(feature = "poseidon_bn254_x5_5")] 272 | (Curve::Bn254, 5, 5) => { 273 | #[path = "./bn254_x5_5_result.rs"] 274 | pub mod bn254_x5_5_result; 275 | parse_vec(bn254_x5_5_result::RESULT.to_vec()) 276 | } 277 | #[cfg(feature = "poseidon_bn254_x5_3")] 278 | (Curve::Bn254, 5, 3) => { 279 | #[path = "./bn254_x5_3_result.rs"] 280 | pub mod bn254_x5_3_result; 281 | parse_vec(bn254_x5_3_result::RESULT.to_vec()) 282 | } 283 | _ => unimplemented!(), 284 | } 285 | } 286 | 287 | pub fn get_poseidon_data( 288 | rounds: &[&str], 289 | mds: &[&[&str]], 290 | full_rounds: u8, 291 | partial_rounds: u8, 292 | width: u8, 293 | exp: i8, 294 | ) -> Result { 295 | let rounds = parse_vec(rounds.to_vec())?; 296 | let mds = parse_matrix(mds.iter().map(|x| x.to_vec()).collect::>())?; 297 | Ok(PoseidonData::new( 298 | mds, 299 | rounds, 300 | full_rounds, 301 | partial_rounds, 302 | width, 303 | exp, 304 | )) 305 | } 306 | -------------------------------------------------------------------------------- /assets/webb-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly-2022-01-06" 3 | components = ["rustfmt", "clippy"] 4 | targets = ["wasm32-unknown-unknown"] 5 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | condense_wildcard_suffixes = true 2 | format_code_in_doc_comments = true 3 | max_width = 100 4 | hard_tabs = true 5 | imports_granularity="Crate" 6 | overflow_delimited_expr = true 7 | reorder_impl_items = true 8 | use_field_init_shorthand = true 9 | wrap_comments = true -------------------------------------------------------------------------------- /scripts/bench.sh: -------------------------------------------------------------------------------- 1 | cargo bench --features "r1cs, test" -- --nocapture -------------------------------------------------------------------------------- /scripts/build-wasm.sh: -------------------------------------------------------------------------------- 1 | cargo build \ 2 | --target wasm32-unknown-unknown \ 3 | --release \ 4 | --no-default-features \ 5 | --workspace \ 6 | --exclude arkworks-circom-verifier \ 7 | --exclude arkworks-benchmarks -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | # Build each crate with isolated features 2 | BASEDIR=$(dirname "$0") 3 | 4 | # Native Gadgets 5 | cargo build -p arkworks-native-gadgets --release --no-default-features && \ 6 | cargo build -p arkworks-native-gadgets --release --no-default-features --features parallel && \ 7 | cargo build -p arkworks-native-gadgets --release --all-features && \ 8 | 9 | # R1CS Gadgets 10 | cargo build -p arkworks-r1cs-gadgets --release --no-default-features && \ 11 | cargo build -p arkworks-r1cs-gadgets --release --no-default-features --features parallel && \ 12 | cargo build -p arkworks-r1cs-gadgets --release --all-features && \ 13 | 14 | # R1CS Circuits 15 | cargo build -p arkworks-r1cs-circuits --release --no-default-features && \ 16 | cargo build -p arkworks-r1cs-circuits --release --no-default-features --features parallel && \ 17 | cargo build -p arkworks-r1cs-circuits --release --all-features && \ 18 | 19 | # Arkworks Utils 20 | cargo build -p arkworks-utils --release --no-default-features && \ 21 | cargo build -p arkworks-utils --release --no-default-features --features parallel && \ 22 | cargo build -p arkworks-utils --release --all-features && \ 23 | 24 | # Arkworks Setups 25 | cargo build -p arkworks-setups --release --no-default-features && \ 26 | cargo build -p arkworks-setups --release --no-default-features --features parallel && \ 27 | cargo build -p arkworks-setups --release --no-default-features --features aead && \ 28 | cargo build -p arkworks-setups --release --all-features 29 | 30 | # PLONK gadgets 31 | cargo build --manifest-path $BASEDIR/../arkworks-plonk-gadgets/Cargo.toml --release --no-default-features && \ 32 | cargo build --manifest-path $BASEDIR/../arkworks-plonk-gadgets/Cargo.toml --release && \ 33 | 34 | # PLONK circuits 35 | cargo build --manifest-path $BASEDIR/../arkworks-plonk-gadgets/Cargo.toml --release --no-default-features && \ 36 | cargo build --manifest-path $BASEDIR/../arkworks-plonk-gadgets/Cargo.toml --release -------------------------------------------------------------------------------- /scripts/clippy.sh: -------------------------------------------------------------------------------- 1 | cargo clippy -------------------------------------------------------------------------------- /scripts/fmt-check.sh: -------------------------------------------------------------------------------- 1 | cargo fmt --all -- --check -------------------------------------------------------------------------------- /scripts/init.sh: -------------------------------------------------------------------------------- 1 | if [[ $(cargo --version) ]]; then 2 | echo "Found cargo" 3 | else 4 | curl https://sh.rustup.rs -sSf | sh -s -- -y 5 | source $HOME/.cargo/env 6 | export PATH=$HOME/.cargo/bin:$PATH 7 | fi -------------------------------------------------------------------------------- /scripts/test.sh: -------------------------------------------------------------------------------- 1 | BASEDIR=$(dirname "$0") 2 | 3 | cargo test --release --features plonk --features r1cs && \ 4 | cargo test --manifest-path $BASEDIR/../arkworks-plonk-circuits/Cargo.toml --release && \ 5 | cargo test --manifest-path $BASEDIR/../arkworks-plonk-gadgets/Cargo.toml --release 6 | --------------------------------------------------------------------------------