├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── pull_request_template.md └── workflows │ ├── cargo-license.yaml │ ├── secrets_scanner.yaml │ └── solidity_verifier_generator.yml ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── SECURITY.md ├── Verifier.sol ├── bellman_vk_codegen ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── PlonkUnrolledForEthereum.pdf ├── deposit_vk.key ├── src │ └── lib.rs └── template.sol └── deny.toml /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Use this template for reporting issues 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | --- 8 | 9 | ### 🐛 Bug Report 10 | 11 | #### 📝 Description 12 | 13 | Provide a clear and concise description of the bug. 14 | 15 | #### 🔄 Reproduction Steps 16 | 17 | Steps to reproduce the behaviour 18 | 19 | #### 🤔 Expected Behavior 20 | 21 | Describe what you expected to happen. 22 | 23 | #### 😯 Current Behavior 24 | 25 | Describe what actually happened. 26 | 27 | #### 🖥️ Environment 28 | 29 | Any relevant environment details. 30 | 31 | #### 📋 Additional Context 32 | 33 | Add any other context about the problem here. If applicable, add screenshots to help explain. 34 | 35 | #### 📎 Log Output 36 | 37 | ``` 38 | Paste any relevant log output here. 39 | ``` 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Use this template for requesting features 4 | title: '' 5 | labels: feat 6 | assignees: '' 7 | --- 8 | 9 | ### 🌟 Feature Request 10 | 11 | #### 📝 Description 12 | 13 | Provide a clear and concise description of the feature you'd like to see. 14 | 15 | #### 🤔 Rationale 16 | 17 | Explain why this feature is important and how it benefits the project. 18 | 19 | #### 📋 Additional Context 20 | 21 | Add any other context or information about the feature request here. 22 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | # What ❔ 2 | 3 | 4 | 5 | 6 | 7 | ## Why ❔ 8 | 9 | 10 | 11 | 12 | ## Checklist 13 | 14 | 15 | 16 | 17 | - [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). 18 | - [ ] Tests for the changes have been added / updated. 19 | - [ ] Documentation comments have been added / updated. 20 | - [ ] Code has been formatted via `zk fmt` and `zk lint`. 21 | -------------------------------------------------------------------------------- /.github/workflows/cargo-license.yaml: -------------------------------------------------------------------------------- 1 | name: Cargo license check 2 | on: pull_request 3 | jobs: 4 | cargo-deny: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v3 8 | - uses: EmbarkStudios/cargo-deny-action@v1 9 | -------------------------------------------------------------------------------- /.github/workflows/secrets_scanner.yaml: -------------------------------------------------------------------------------- 1 | name: Leaked Secrets Scan 2 | on: [pull_request] 3 | jobs: 4 | TruffleHog: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - name: Checkout code 8 | uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3 9 | with: 10 | fetch-depth: 0 11 | - name: TruffleHog OSS 12 | uses: trufflesecurity/trufflehog@0c66d30c1f4075cee1aada2e1ab46dabb1b0071a 13 | with: 14 | path: ./ 15 | base: ${{ github.event.repository.default_branch }} 16 | head: HEAD 17 | extra_args: --debug --only-verified 18 | -------------------------------------------------------------------------------- /.github/workflows/solidity_verifier_generator.yml: -------------------------------------------------------------------------------- 1 | name: Solidity verifier generator 2 | 3 | # Only trigger, when the deployment workflow succeeded 4 | on: 5 | workflow_dispatch: 6 | inputs: 7 | scheduler_vk_json_file_link: 8 | description: "Link to scheduler verification key json file" 9 | type: string 10 | required: true 11 | default: "https://github.com/matter-labs/zksync-2-dev/blob/main/core/bin/verification_key_generator_and_server/data/verification_0_key.json" 12 | 13 | jobs: 14 | generate-solidity-verifier: 15 | runs-on: [matterlabs-ci-runner] 16 | steps: 17 | - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3 18 | with: 19 | ref: ${{ github.event.inputs.target_branch }} 20 | submodules: "recursive" 21 | token: ${{ secrets.ZKSYNC_ADMIN_BOT_ORG_REPO_WRITE }} 22 | - name: Setup Rust 23 | run: | 24 | curl https://sh.rustup.rs -sSf | bash -s -- -y 25 | source "$HOME/.cargo/env" 26 | sudo apt update && sudo apt install clang openssl libssl-dev gcc g++ pkg-config build-essential libclang-dev -y 27 | - name: Estimate circuit limit 28 | run: | 29 | git config --global --add url."https://${{ secrets.ZKSYNC_ADMIN_BOT_ORG_REPO_WRITE }}:x-oauth-basic@github.com/".insteadOf ssh://git@github.com/ 30 | git config --global --add url."https://${{ secrets.ZKSYNC_ADMIN_BOT_ORG_REPO_WRITE }}:x-oauth-basic@github.com/".insteadOf https://github.com/ 31 | source "$HOME/.cargo/env" 32 | echo "Downloading verification key json file from ${{ inputs.scheduler_vk_json_file_link }}" 33 | curl -o vk.json "${{ inputs.scheduler_vk_json_file_link }}" 34 | echo "Generating Verifier.sol" 35 | cargo run --release -- --encoding json --verification-key vk.json 36 | - uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3 37 | with: 38 | path: ./circuit_limit_${{ matrix.key }}.txt 39 | 40 | create-pr: 41 | runs-on: [ matterlabs-ci-runner ] 42 | needs: [ "generate-solidity-verifier" ] 43 | steps: 44 | - uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b # v3 45 | with: 46 | ref: ${{ github.event.inputs.target_branch }} 47 | submodules: "recursive" 48 | token: ${{ secrets.ZKSYNC_ADMIN_BOT_ORG_REPO_WRITE }} 49 | - uses: actions/download-artifact@9782bd6a9848b53b110e712e20e42d89988822b7 # v3 50 | with: 51 | path: hardhat/contracts 52 | - name: Create Pull Request 53 | id: cpr 54 | uses: peter-evans/create-pull-request@2b011faafdcbc9ceb11414d64d0573f37c774b04 # v4 55 | with: 56 | token: ${{ secrets.ZKSYNC_ADMIN_BOT_ORG_REPO_WRITE }} 57 | base: ${{ github.event.inputs.target_branch }} 58 | commit-message: update generated verifier.sol file 59 | committer: zksync-admin-bot2 60 | author: zksync-admin-bot2 61 | signoff: false 62 | branch: update-verifier-sol 63 | branch-suffix: short-commit-hash 64 | delete-branch: true 65 | title: Update verifier solidity file from branch ${{ github.event.inputs.target_branch }} 66 | body: | 67 | Update generated verifier solidity file from branch ${{ github.event.inputs.target_branch }} 68 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | Hello! Thanks for your interest in joining the mission to accelerate the mass adoption of crypto for personal 4 | sovereignty! We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes! 5 | 6 | ## Ways to contribute 7 | 8 | There are many ways to contribute to the ZK Stack: 9 | 10 | 1. Open issues: if you find a bug, have something you believe needs to be fixed, or have an idea for a feature, please 11 | open an issue. 12 | 2. Add color to existing issues: provide screenshots, code snippets, and whatever you think would be helpful to resolve 13 | issues. 14 | 3. Resolve issues: either by showing an issue isn't a problem and the current state is ok as is or by fixing the problem 15 | and opening a PR. 16 | 4. Report security issues, see [our security policy](./github/SECURITY.md). 17 | 5. [Join the team!](https://matterlabs.notion.site/Shape-the-future-of-Ethereum-at-Matter-Labs-dfb3b5a037044bb3a8006af2eb0575e0) 18 | 19 | ## Fixing issues 20 | 21 | To contribute code fixing issues, please fork the repo, fix an issue, commit, add documentation as per the PR template, 22 | and the repo's maintainers will review the PR. 23 | [here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) 24 | for guidance how to work with PRs created from a fork. 25 | 26 | ## Licenses 27 | 28 | If you contribute to this project, your contributions will be made to the project under both Apache 2.0 and the MIT 29 | license. 30 | 31 | ## Resources 32 | 33 | We aim to make it as easy as possible to contribute to the mission. This is still WIP, and we're happy for contributions 34 | and suggestions here too. Some resources to help: 35 | 36 | 1. [In-repo docs aimed at developers](docs) 37 | 2. [zkSync Era docs!](https://era.zksync.io/docs/) 38 | 3. Company links can be found in the [repo's readme](README.md) 39 | 40 | ## Code of Conduct 41 | 42 | Be polite and respectful. 43 | 44 | ### Thank you 45 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "bellman_vk_codegen", 4 | ] 5 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | This software includes components from third parties. For a full list of these components and their licenses, 2 | see the THIRD PARTY NOTICES file. 3 | 4 | Apache License 5 | Version 2.0, January 2004 6 | http://www.apache.org/licenses/ 7 | 8 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 9 | 10 | 1. Definitions. 11 | 12 | "License" shall mean the terms and conditions for use, reproduction, 13 | and distribution as defined by Sections 1 through 9 of this document. 14 | 15 | "Licensor" shall mean the copyright owner or entity authorized by 16 | the copyright owner that is granting the License. 17 | 18 | "Legal Entity" shall mean the union of the acting entity and all 19 | other entities that control, are controlled by, or are under common 20 | control with that entity. For the purposes of this definition, 21 | "control" means (i) the power, direct or indirect, to cause the 22 | direction or management of such entity, whether by contract or 23 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 24 | outstanding shares, or (iii) beneficial ownership of such entity. 25 | 26 | "You" (or "Your") shall mean an individual or Legal Entity 27 | exercising permissions granted by this License. 28 | 29 | "Source" form shall mean the preferred form for making modifications, 30 | including but not limited to software source code, documentation 31 | source, and configuration files. 32 | 33 | "Object" form shall mean any form resulting from mechanical 34 | transformation or translation of a Source form, including but 35 | not limited to compiled object code, generated documentation, 36 | and conversions to other media types. 37 | 38 | "Work" shall mean the work of authorship, whether in Source or 39 | Object form, made available under the License, as indicated by a 40 | copyright notice that is included in or attached to the work 41 | (an example is provided in the Appendix below). 42 | 43 | "Derivative Works" shall mean any work, whether in Source or Object 44 | form, that is based on (or derived from) the Work and for which the 45 | editorial revisions, annotations, elaborations, or other modifications 46 | represent, as a whole, an original work of authorship. For the purposes 47 | of this License, Derivative Works shall not include works that remain 48 | separable from, or merely link (or bind by name) to the interfaces of, 49 | the Work and Derivative Works thereof. 50 | 51 | "Contribution" shall mean any work of authorship, including 52 | the original version of the Work and any modifications or additions 53 | to that Work or Derivative Works thereof, that is intentionally 54 | submitted to Licensor for inclusion in the Work by the copyright owner 55 | or by an individual or Legal Entity authorized to submit on behalf of 56 | the copyright owner. For the purposes of this definition, "submitted" 57 | means any form of electronic, verbal, or written communication sent 58 | to the Licensor or its representatives, including but not limited to 59 | communication on electronic mailing lists, source code control systems, 60 | and issue tracking systems that are managed by, or on behalf of, the 61 | Licensor for the purpose of discussing and improving the Work, but 62 | excluding communication that is conspicuously marked or otherwise 63 | designated in writing by the copyright owner as "Not a Contribution." 64 | 65 | "Contributor" shall mean Licensor and any individual or Legal Entity 66 | on behalf of whom a Contribution has been received by Licensor and 67 | subsequently incorporated within the Work. 68 | 69 | 2. Grant of Copyright License. Subject to the terms and conditions of 70 | this License, each Contributor hereby grants to You a perpetual, 71 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 72 | copyright license to reproduce, prepare Derivative Works of, 73 | publicly display, publicly perform, sublicense, and distribute the 74 | Work and such Derivative Works in Source or Object form. 75 | 76 | 3. Grant of Patent License. Subject to the terms and conditions of 77 | this License, each Contributor hereby grants to You a perpetual, 78 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 79 | (except as stated in this section) patent license to make, have made, 80 | use, offer to sell, sell, import, and otherwise transfer the Work, 81 | where such license applies only to those patent claims licensable 82 | by such Contributor that are necessarily infringed by their 83 | Contribution(s) alone or by combination of their Contribution(s) 84 | with the Work to which such Contribution(s) was submitted. If You 85 | institute patent litigation against any entity (including a 86 | cross-claim or counterclaim in a lawsuit) alleging that the Work 87 | or a Contribution incorporated within the Work constitutes direct 88 | or contributory patent infringement, then any patent licenses 89 | granted to You under this License for that Work shall terminate 90 | as of the date such litigation is filed. 91 | 92 | 4. Redistribution. You may reproduce and distribute copies of the 93 | Work or Derivative Works thereof in any medium, with or without 94 | modifications, and in Source or Object form, provided that You 95 | meet the following conditions: 96 | 97 | (a) You must give any other recipients of the Work or 98 | Derivative Works a copy of this License; and 99 | 100 | (b) You must cause any modified files to carry prominent notices 101 | stating that You changed the files; and 102 | 103 | (c) You must retain, in the Source form of any Derivative Works 104 | that You distribute, all copyright, patent, trademark, and 105 | attribution notices from the Source form of the Work, 106 | excluding those notices that do not pertain to any part of 107 | the Derivative Works; and 108 | 109 | (d) If the Work includes a "NOTICE" text file as part of its 110 | distribution, then any Derivative Works that You distribute must 111 | include a readable copy of the attribution notices contained 112 | within such NOTICE file, excluding those notices that do not 113 | pertain to any part of the Derivative Works, in at least one 114 | of the following places: within a NOTICE text file distributed 115 | as part of the Derivative Works; within the Source form or 116 | documentation, if provided along with the Derivative Works; or, 117 | within a display generated by the Derivative Works, if and 118 | wherever such third-party notices normally appear. The contents 119 | of the NOTICE file are for informational purposes only and 120 | do not modify the License. You may add Your own attribution 121 | notices within Derivative Works that You distribute, alongside 122 | or as an addendum to the NOTICE text from the Work, provided 123 | that such additional attribution notices cannot be construed 124 | as modifying the License. 125 | 126 | You may add Your own copyright statement to Your modifications and 127 | may provide additional or different license terms and conditions 128 | for use, reproduction, or distribution of Your modifications, or 129 | for any such Derivative Works as a whole, provided Your use, 130 | reproduction, and distribution of the Work otherwise complies with 131 | the conditions stated in this License. 132 | 133 | 5. Submission of Contributions. Unless You explicitly state otherwise, 134 | any Contribution intentionally submitted for inclusion in the Work 135 | by You to the Licensor shall be under the terms and conditions of 136 | this License, without any additional terms or conditions. 137 | Notwithstanding the above, nothing herein shall supersede or modify 138 | the terms of any separate license agreement you may have executed 139 | with Licensor regarding such Contributions. 140 | 141 | 6. Trademarks. This License does not grant permission to use the trade 142 | names, trademarks, service marks, or product names of the Licensor, 143 | except as required for reasonable and customary use in describing the 144 | origin of the Work and reproducing the content of the NOTICE file. 145 | 146 | 7. Disclaimer of Warranty. Unless required by applicable law or 147 | agreed to in writing, Licensor provides the Work (and each 148 | Contributor provides its Contributions) on an "AS IS" BASIS, 149 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 150 | implied, including, without limitation, any warranties or conditions 151 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 152 | PARTICULAR PURPOSE. You are solely responsible for determining the 153 | appropriateness of using or redistributing the Work and assume any 154 | risks associated with Your exercise of permissions under this License. 155 | 156 | 8. Limitation of Liability. In no event and under no legal theory, 157 | whether in tort (including negligence), contract, or otherwise, 158 | unless required by applicable law (such as deliberate and grossly 159 | negligent acts) or agreed to in writing, shall any Contributor be 160 | liable to You for damages, including any direct, indirect, special, 161 | incidental, or consequential damages of any character arising as a 162 | result of this License or out of the use or inability to use the 163 | Work (including but not limited to damages for loss of goodwill, 164 | work stoppage, computer failure or malfunction, or any and all 165 | other commercial damages or losses), even if such Contributor 166 | has been advised of the possibility of such damages. 167 | 168 | 9. Accepting Warranty or Additional Liability. While redistributing 169 | the Work or Derivative Works thereof, You may choose to offer, 170 | and charge a fee for, acceptance of support, warranty, indemnity, 171 | or other liability obligations and/or rights consistent with this 172 | License. However, in accepting such obligations, You may act only 173 | on Your own behalf and on Your sole responsibility, not on behalf 174 | of any other Contributor, and only if You agree to indemnify, 175 | defend, and hold each Contributor harmless for any liability 176 | incurred by, or claims asserted against, such Contributor by reason 177 | of your accepting any such warranty or additional liability. 178 | 179 | END OF TERMS AND CONDITIONS 180 | 181 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | This software includes components from third parties. For a full list of these components and their licenses, 2 | see the THIRD PARTY NOTICES file. 3 | 4 | MIT License 5 | 6 | Copyright (c) 2019 Matter Labs 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!WARNING] 2 | > This crate has been archived. Development has moved to the [zksync-crypto](https://github.com/matter-labs/zksync-crypto) repository. 3 | > Please use it instead. 4 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | We truly appreciate efforts to discover and disclose security issues responsibly! 4 | 5 | ## Vulnerabilities 6 | 7 | If you'd like to report a security issue in the repositories of matter-labs organization, please proceed to our 8 | [Bug Bounty Program on Immunefi](https://era.zksync.io/docs/reference/troubleshooting/audit-bug-bounty.html#bug-bounty-program). 9 | 10 | ## Other Security Issues 11 | 12 | We take an impact-first approach instead of a rules-first approach. Therefore, if you believe you found the impactful 13 | issue but can't report it via the Bug Bounty, please email us at 14 | [security@matterlabs.dev](mailto:security@matterlabs.dev). 15 | 16 | ### PGP Key 17 | 18 | The following PGP key may be used to communicate sensitive information to developers: 19 | 20 | Fingerprint: `5FED B2D0 EA2C 4906 DD66 71D7 A2C5 0B40 CE3C F297` 21 | 22 | ``` 23 | -----BEGIN PGP PUBLIC KEY BLOCK----- 24 | 25 | mQINBGEBmQkBEAD6tlkBEZFMvR8kOgxXX857nC2+oTik6TopJz4uCskuqDaeldMy 26 | l+26BBzLkIeO1loS+bzVgnNFJRrGt9gv98MzNEHJVv6D7GsSLlUX/pz7Lxn0J4ry 27 | o5XIk3MQTCUBdaXGs6GBLl5Xe8o+zNj4MKd4zjgDLinITNlE/YZCDsXyvYS3YFTQ 28 | cwaUTNlawkKgw4BLaEqwB2JuyEhI9wx5X7ibjFL32sWMolYsNAlzFQzM09HCurTn 29 | q0DYau9kPJARcEk9/DK2iq0z3gMCQ8iRTDaOWd8IbSP3HxcEoM5j5ZVAlULmjmUE 30 | StDaMPLj0Kh01Tesh/j+vjchPXHT0n4zqi1+KOesAOk7SIwLadHfQMTpkU7G2fR1 31 | BrA5MtlzY+4Rm6o7qu3dpZ+Nc4iM3FUnaQRpvn4g5nTh8vjG94OCzX8DXWrCKyxx 32 | amCs9PLDYOpx84fXYv4frkWpKh2digDSUGKhoHaOSnqyyvu3BNWXBCQZJ20rqEIu 33 | sXOQMxWIoWCOOPRRvrHrKDA2hpoKjs3pGsProfpVRzb9702jhWpTfbDp9WjQlFtX 34 | 2ZIDxlwAxcugClgrp5JiUxvhg2A9lDNwCF7r1e68uNv5usBZQVKPJmnvS2nWgKy8 35 | x9oJsnwrEjxwiRHd34UvfMkwY9RENSJ+NoXqBdS7Lwz4m6vgbzq6K56WPQARAQAB 36 | tCRaa1N5bmMgU2VjdXJpdHkgPHNlY3VyaXR5QHprc3luYy5pbz6JAk4EEwEKADgW 37 | IQRf7bLQ6ixJBt1mcdeixQtAzjzylwUCYQGZCQIbAwULCQgHAgYVCgkICwIEFgID 38 | AQIeAQIXgAAKCRCixQtAzjzyl5y8EAC/T3oq88Dak2b+5TlWdU2Gpm6924eAqlMt 39 | y1KksDezzNQUlPiCUVllpin2PIjU/S+yzMWKXJA04LoVkEPfPOWjAaavLOjRumxu 40 | MR6P2dVUg1InqzYVsJuRhKSpeexzNA5qO2BPM7/I2Iea1IoJPjogGbfXCo0r5kne 41 | KU7a5GEa9eDHxpHTsbphQe2vpQ1239mUJrFpzAvILn6jV1tawMn5pNCXbsa8l6l2 42 | gtlyQPdOQECy77ZJxrgzaUBcs/RPzUGhwA/qNuvpF0whaCvZuUFMVuCTEu5LZka2 43 | I9Rixy+3jqBeONBgb+Fiz5phbiMX33M9JQwGONFaxdvpFTerLwPK2N1T8zcufa01 44 | ypzkWGheScFZemBxUwXwK4x579wjsnfrY11w0p1jtDgPTnLlXUA2mom4+7MyXPg0 45 | F75qh6vU1pdXaCVkruFgPVtIw+ccw2AxD50iZQ943ZERom9k165dR9+QxOVMXQ4P 46 | VUxsFZWvK70/s8TLjsGljvSdSOa85iEUqSqh0AlCwIAxLMiDwh5s/ZgiHoIM6Xih 47 | oCpuZyK9p0dn+DF/XkgAZ/S91PesMye3cGm6M5r0tS26aoc2Pk6X37Hha1pRALwo 48 | MOHyaGjc/jjcXXxv6o55ALrOrzS0LQmLZ+EHuteCT15kmeY3kqYJ3og62KgiDvew 49 | dKHENvg7d7kCDQRhAZleARAA6uD6WfdqGeKV5i170+kLsxR3QGav0qGNAbxpSJyn 50 | iHQ8u7mQk3S+ziwN2AAopfBk1je+vCWtEGC3+DWRRfJSjLbtaBG8e6kLP3/cGA75 51 | qURz6glTG4nl5fcEAa6B1st0OxjVWiSLX3g/yjz8lznQb9awuRjdeHMnyx5DsJUN 52 | d+Iu5KxGupQvKGOMKivSvC8VWk9taaQRpRF+++6stLCDk3ZtlxiopMs3X2jAp6xG 53 | sOBbix1cv9BTsfaiL7XDL/gviqBPXYY5L42x6+jnPo5lROfnlLYkWrv6KZr7HD4k 54 | tRXeaSwxLD2EkUyb16Jpp0be/ofvBtITGUDDLCGBiaXtx/v8d52MARjsyLJSYloj 55 | 1yiW01LfAiWHUC4z5jl2T7E7sicrlLH1M8Z6WbuqjdeaYwtfyPA2YCKr/3fn6pIo 56 | D+pYaBSESmhA92P+XVaf5y2BZ6Qf8LveDpWwsVGdBGh9T0raA1ooe1GESLjmIjUa 57 | z5AeQ/uXL5Md9I6bpMUUJYQiH19RPcFlJriI3phXyyf6Wlkk8oVEeCWyzcmw+x1V 58 | deRTvE2x4WIwKGLXRNjin2j1AP7vU2HaNwlPrLijqdyi68+0irRQONoH7Qonr4ca 59 | xWgL+pAaa3dWxf0xqK7uZFp4aTVWlr2uXtV/eaUtLmGMCU0jnjb109wg5L0F7WRT 60 | PfEAEQEAAYkCNgQYAQoAIBYhBF/tstDqLEkG3WZx16LFC0DOPPKXBQJhAZleAhsM 61 | AAoJEKLFC0DOPPKXAAEP/jK7ch9GkoaYlsuqY/aHtxEwVddUDOxjyn3FMDoln85L 62 | /n8AmLQb2bcpKSqpaJwMbmfEyr5MDm8xnsBTfx3u6kgaLOWfKxjLQ6PM7kgIMdi4 63 | bfaRRuSEI1/R6c/hNpiGnzAeeexldH1we+eH1IVmh4crdat49S2xh7Qlv9ahvgsP 64 | LfKl3rJ+aaX/Ok0AHzhvSfhFpPr1gAaGeaRt+rhlZsx2QyG4Ez8p2nDAcAzPiB3T 65 | 73ENoBIX6mTPfPm1UgrRyFKBqtUzAodz66j3r6ebBlWzIRg8iZenVMAxzjINAsxN 66 | w1Bzfgsi5ZespfsSlmEaa7jJkqqDuEcLa2YuiFAue7Euqwz1aGeq1GfTicQioSCb 67 | Ur/LGyz2Mj3ykbaP8p5mFVcUN51yQy6OcpvR/W1DfRT9SHFT/bCf9ixsjB2HlZGo 68 | uxPJowwqmMgHd755ZzPDUM9YDgLI1yXdcYshObv3Wq537JAxnZJCGRK4Y8SwrMSh 69 | 8WRxlaM0AGWXiJFIDD4bQPIdnF3X8w0cGWE5Otkb8mMHOT+rFTVlDODwm1zF6oIG 70 | PTwfVrpiZBwiUtfJol1exr/MzSPyGoJnYs3cRf2E3O+D1LbcR8w0LbjGuUy38Piz 71 | ZO/vCeyJ3JZC5kE8nD+XBA4idwzh0BKEfH9t+WchQ3Up9rxyzLyQamoqt5Xby4pY 72 | =xkM3 73 | -----END PGP PUBLIC KEY BLOCK----- 74 | ``` 75 | -------------------------------------------------------------------------------- /Verifier.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0 <0.7.0; 2 | 3 | library PairingsBn254 { 4 | uint256 constant q_mod = 21888242871839275222246405745257275088696311157297823662689037894645226208583; 5 | uint256 constant r_mod = 21888242871839275222246405745257275088548364400416034343698204186575808495617; 6 | 7 | struct G1Point { 8 | uint256 X; 9 | uint256 Y; 10 | } 11 | 12 | struct Fr { 13 | uint256 value; 14 | } 15 | 16 | function new_fr(uint256 fr) internal pure returns (Fr memory) { 17 | require(fr < r_mod); 18 | return Fr({value: fr}); 19 | } 20 | 21 | function copy(Fr memory self) internal pure returns (Fr memory n) { 22 | n.value = self.value; 23 | } 24 | 25 | function assign(Fr memory self, Fr memory other) internal pure { 26 | self.value = other.value; 27 | } 28 | 29 | function inverse(Fr memory fr) internal view returns (Fr memory) { 30 | assert(fr.value != 0); 31 | return pow(fr, r_mod-2); 32 | } 33 | 34 | function add_assign(Fr memory self, Fr memory other) internal pure { 35 | self.value = addmod(self.value, other.value, r_mod); 36 | } 37 | 38 | function sub_assign(Fr memory self, Fr memory other) internal pure { 39 | self.value = addmod(self.value, r_mod - other.value, r_mod); 40 | } 41 | 42 | function mul_assign(Fr memory self, Fr memory other) internal pure { 43 | self.value = mulmod(self.value, other.value, r_mod); 44 | } 45 | 46 | function pow(Fr memory self, uint256 power) internal view returns (Fr memory) { 47 | uint256[6] memory input = [32, 32, 32, self.value, power, r_mod]; 48 | uint256[1] memory result; 49 | bool success; 50 | assembly { 51 | success := staticcall(gas(), 0x05, input, 0xc0, result, 0x20) 52 | } 53 | require(success); 54 | return Fr({value: result[0]}); 55 | } 56 | 57 | // Encoding of field elements is: X[0] * z + X[1] 58 | struct G2Point { 59 | uint[2] X; 60 | uint[2] Y; 61 | } 62 | 63 | function P1() internal pure returns (G1Point memory) { 64 | return G1Point(1, 2); 65 | } 66 | 67 | function new_g1(uint256 x, uint256 y) internal pure returns (G1Point memory) { 68 | return G1Point(x, y); 69 | } 70 | 71 | function new_g2(uint256[2] memory x, uint256[2] memory y) internal pure returns (G2Point memory) { 72 | return G2Point(x, y); 73 | } 74 | 75 | function copy_g1(G1Point memory self) internal pure returns (G1Point memory result) { 76 | result.X = self.X; 77 | result.Y = self.Y; 78 | } 79 | 80 | function P2() internal pure returns (G2Point memory) { 81 | // for some reason ethereum expects to have c1*v + c0 form 82 | 83 | return G2Point( 84 | [0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 85 | 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed], 86 | [0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b, 87 | 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa] 88 | ); 89 | } 90 | 91 | function negate(G1Point memory self) internal pure { 92 | // The prime q in the base field F_q for G1 93 | if (self.X == 0 && self.Y == 0) 94 | return; 95 | self.Y = q_mod - self.Y; 96 | } 97 | 98 | // function is_infinity(G1Point memory p) internal pure returns (bool) { 99 | // if (p.X == 0 && p.Y == 0) { 100 | // return true; 101 | // } 102 | // return false; 103 | // } 104 | 105 | function point_add(G1Point memory p1, G1Point memory p2) 106 | internal view returns (G1Point memory r) 107 | { 108 | point_add_into_dest(p1, p2, r); 109 | return r; 110 | } 111 | 112 | function point_add_assign(G1Point memory p1, G1Point memory p2) 113 | internal view 114 | { 115 | point_add_into_dest(p1, p2, p1); 116 | } 117 | 118 | function point_add_into_dest(G1Point memory p1, G1Point memory p2, G1Point memory dest) 119 | internal view 120 | { 121 | uint256[4] memory input; 122 | if (p2.X == 0 && p2.Y == 0) { 123 | // we add zero, nothing happens 124 | dest.X = p1.X; 125 | dest.Y = p1.Y; 126 | return; 127 | } else if (p1.X == 0 && p1.Y == 0) { 128 | // we add into zero, and we add non-zero point 129 | dest.X = p2.X; 130 | dest.Y = p2.Y; 131 | return; 132 | } else { 133 | input[0] = p1.X; 134 | input[1] = p1.Y; 135 | input[2] = p2.X; 136 | input[3] = p2.Y; 137 | } 138 | bool success = false; 139 | assembly { 140 | success := staticcall(gas(), 6, input, 0x80, dest, 0x40) 141 | } 142 | require(success); 143 | } 144 | 145 | function point_sub_assign(G1Point memory p1, G1Point memory p2) 146 | internal view 147 | { 148 | point_sub_into_dest(p1, p2, p1); 149 | } 150 | 151 | function point_sub_into_dest(G1Point memory p1, G1Point memory p2, G1Point memory dest) 152 | internal view 153 | { 154 | uint256[4] memory input; 155 | if (p2.X == 0 && p2.Y == 0) { 156 | // we subtracted zero, nothing happens 157 | dest.X = p1.X; 158 | dest.Y = p1.Y; 159 | return; 160 | } else if (p1.X == 0 && p1.Y == 0) { 161 | // we subtract from zero, and we subtract non-zero point 162 | dest.X = p2.X; 163 | dest.Y = q_mod - p2.Y; 164 | return; 165 | } else { 166 | input[0] = p1.X; 167 | input[1] = p1.Y; 168 | input[2] = p2.X; 169 | input[3] = q_mod - p2.Y; 170 | } 171 | bool success = false; 172 | assembly { 173 | success := staticcall(gas(), 6, input, 0x80, dest, 0x40) 174 | } 175 | require(success); 176 | } 177 | 178 | 179 | function point_mul(G1Point memory p, Fr memory s) 180 | internal view returns (G1Point memory r) 181 | { 182 | point_mul_into_dest(p, s, r); 183 | return r; 184 | } 185 | 186 | function point_mul_assign(G1Point memory p, Fr memory s) 187 | internal view 188 | { 189 | point_mul_into_dest(p, s, p); 190 | } 191 | 192 | function point_mul_into_dest(G1Point memory p, Fr memory s, G1Point memory dest) 193 | internal view 194 | { 195 | uint[3] memory input; 196 | input[0] = p.X; 197 | input[1] = p.Y; 198 | input[2] = s.value; 199 | bool success; 200 | assembly { 201 | success := staticcall(gas(), 7, input, 0x60, dest, 0x40) 202 | } 203 | require(success); 204 | } 205 | 206 | function pairing(G1Point[] memory p1, G2Point[] memory p2) 207 | internal view returns (bool) 208 | { 209 | require(p1.length == p2.length); 210 | uint elements = p1.length; 211 | uint inputSize = elements * 6; 212 | uint[] memory input = new uint[](inputSize); 213 | for (uint i = 0; i < elements; i++) 214 | { 215 | input[i * 6 + 0] = p1[i].X; 216 | input[i * 6 + 1] = p1[i].Y; 217 | input[i * 6 + 2] = p2[i].X[0]; 218 | input[i * 6 + 3] = p2[i].X[1]; 219 | input[i * 6 + 4] = p2[i].Y[0]; 220 | input[i * 6 + 5] = p2[i].Y[1]; 221 | } 222 | uint[1] memory out; 223 | bool success; 224 | assembly { 225 | success := staticcall(gas(), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20) 226 | } 227 | require(success); 228 | return out[0] != 0; 229 | } 230 | 231 | /// Convenience method for a pairing check for two pairs. 232 | function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) 233 | internal view returns (bool) 234 | { 235 | G1Point[] memory p1 = new G1Point[](2); 236 | G2Point[] memory p2 = new G2Point[](2); 237 | p1[0] = a1; 238 | p1[1] = b1; 239 | p2[0] = a2; 240 | p2[1] = b2; 241 | return pairing(p1, p2); 242 | } 243 | } 244 | 245 | library TranscriptLibrary { 246 | // flip 0xe000000000000000000000000000000000000000000000000000000000000000; 247 | uint256 constant FR_MASK = 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; 248 | 249 | uint32 constant DST_0 = 0; 250 | uint32 constant DST_1 = 1; 251 | uint32 constant DST_CHALLENGE = 2; 252 | 253 | struct Transcript { 254 | bytes32 state_0; 255 | bytes32 state_1; 256 | uint32 challenge_counter; 257 | } 258 | 259 | function new_transcript() internal pure returns (Transcript memory t) { 260 | t.state_0 = bytes32(0); 261 | t.state_1 = bytes32(0); 262 | t.challenge_counter = 0; 263 | } 264 | 265 | function update_with_u256(Transcript memory self, uint256 value) internal pure { 266 | bytes32 old_state_0 = self.state_0; 267 | self.state_0 = keccak256(abi.encodePacked(DST_0, old_state_0, self.state_1, value)); 268 | self.state_1 = keccak256(abi.encodePacked(DST_1, old_state_0, self.state_1, value)); 269 | } 270 | 271 | function update_with_fr(Transcript memory self, PairingsBn254.Fr memory value) internal pure { 272 | update_with_u256(self, value.value); 273 | } 274 | 275 | function update_with_g1(Transcript memory self, PairingsBn254.G1Point memory p) internal pure { 276 | update_with_u256(self, p.X); 277 | update_with_u256(self, p.Y); 278 | } 279 | 280 | function get_challenge(Transcript memory self) internal pure returns(PairingsBn254.Fr memory challenge) { 281 | bytes32 query = keccak256(abi.encodePacked(DST_CHALLENGE, self.state_0, self.state_1, self.challenge_counter)); 282 | self.challenge_counter += 1; 283 | challenge = PairingsBn254.Fr({value: uint256(query) & FR_MASK}); 284 | } 285 | } 286 | 287 | contract Plonk4VerifierWithAccessToDNext { 288 | using PairingsBn254 for PairingsBn254.G1Point; 289 | using PairingsBn254 for PairingsBn254.G2Point; 290 | using PairingsBn254 for PairingsBn254.Fr; 291 | 292 | using TranscriptLibrary for TranscriptLibrary.Transcript; 293 | 294 | uint256 constant STATE_WIDTH = 4; 295 | 296 | struct VerificationKey { 297 | uint256 domain_size; 298 | uint256 num_inputs; 299 | PairingsBn254.Fr omega; 300 | PairingsBn254.G1Point[STATE_WIDTH+2] selector_commitments; // STATE_WIDTH for witness + multiplication + constant 301 | PairingsBn254.G1Point[1] next_step_selector_commitments; 302 | PairingsBn254.G1Point[STATE_WIDTH] permutation_commitments; 303 | PairingsBn254.Fr[STATE_WIDTH-1] permutation_non_residues; 304 | PairingsBn254.G2Point g2_x; 305 | } 306 | 307 | struct Proof { 308 | uint256[] input_values; 309 | PairingsBn254.G1Point[STATE_WIDTH] wire_commitments; 310 | PairingsBn254.G1Point grand_product_commitment; 311 | PairingsBn254.G1Point[STATE_WIDTH] quotient_poly_commitments; 312 | PairingsBn254.Fr[STATE_WIDTH] wire_values_at_z; 313 | PairingsBn254.Fr[1] wire_values_at_z_omega; 314 | PairingsBn254.Fr grand_product_at_z_omega; 315 | PairingsBn254.Fr quotient_polynomial_at_z; 316 | PairingsBn254.Fr linearization_polynomial_at_z; 317 | PairingsBn254.Fr[STATE_WIDTH-1] permutation_polynomials_at_z; 318 | 319 | PairingsBn254.G1Point opening_at_z_proof; 320 | PairingsBn254.G1Point opening_at_z_omega_proof; 321 | } 322 | 323 | struct PartialVerifierState { 324 | PairingsBn254.Fr alpha; 325 | PairingsBn254.Fr beta; 326 | PairingsBn254.Fr gamma; 327 | PairingsBn254.Fr v; 328 | PairingsBn254.Fr u; 329 | PairingsBn254.Fr z; 330 | PairingsBn254.Fr[] cached_lagrange_evals; 331 | } 332 | 333 | function evaluate_lagrange_poly_out_of_domain( 334 | uint256 poly_num, 335 | uint256 domain_size, 336 | PairingsBn254.Fr memory omega, 337 | PairingsBn254.Fr memory at 338 | ) internal view returns (PairingsBn254.Fr memory res) { 339 | require(poly_num < domain_size); 340 | PairingsBn254.Fr memory one = PairingsBn254.new_fr(1); 341 | PairingsBn254.Fr memory omega_power = omega.pow(poly_num); 342 | res = at.pow(domain_size); 343 | res.sub_assign(one); 344 | assert(res.value != 0); // Vanishing polynomial can not be zero at point `at` 345 | res.mul_assign(omega_power); 346 | 347 | PairingsBn254.Fr memory den = PairingsBn254.copy(at); 348 | den.sub_assign(omega_power); 349 | den.mul_assign(PairingsBn254.new_fr(domain_size)); 350 | 351 | den = den.inverse(); 352 | 353 | res.mul_assign(den); 354 | } 355 | 356 | function batch_evaluate_lagrange_poly_out_of_domain( 357 | uint256[] memory poly_nums, 358 | uint256 domain_size, 359 | PairingsBn254.Fr memory omega, 360 | PairingsBn254.Fr memory at 361 | ) internal view returns (PairingsBn254.Fr[] memory res) { 362 | PairingsBn254.Fr memory one = PairingsBn254.new_fr(1); 363 | PairingsBn254.Fr memory tmp_1 = PairingsBn254.new_fr(0); 364 | PairingsBn254.Fr memory tmp_2 = PairingsBn254.new_fr(domain_size); 365 | PairingsBn254.Fr memory vanishing_at_z = at.pow(domain_size); 366 | vanishing_at_z.sub_assign(one); 367 | // we can not have random point z be in domain 368 | assert(vanishing_at_z.value != 0); 369 | PairingsBn254.Fr[] memory nums = new PairingsBn254.Fr[](poly_nums.length); 370 | PairingsBn254.Fr[] memory dens = new PairingsBn254.Fr[](poly_nums.length); 371 | // numerators in a form omega^i * (z^n - 1) 372 | // denoms in a form (z - omega^i) * N 373 | for (uint i = 0; i < poly_nums.length; i++) { 374 | tmp_1 = omega.pow(poly_nums[i]); // power of omega 375 | nums[i].assign(vanishing_at_z); 376 | nums[i].mul_assign(tmp_1); 377 | 378 | dens[i].assign(at); // (X - omega^i) * N 379 | dens[i].sub_assign(tmp_1); 380 | dens[i].mul_assign(tmp_2); // mul by domain size 381 | } 382 | 383 | PairingsBn254.Fr[] memory partial_products = new PairingsBn254.Fr[](poly_nums.length); 384 | partial_products[0].assign(PairingsBn254.new_fr(1)); 385 | for (uint i = 1; i < dens.length - 1; i++) { 386 | partial_products[i].assign(dens[i-1]); 387 | partial_products[i].mul_assign(dens[i]); 388 | } 389 | 390 | tmp_2.assign(partial_products[partial_products.length - 1]); 391 | tmp_2.mul_assign(dens[dens.length - 1]); 392 | tmp_2 = tmp_2.inverse(); // tmp_2 contains a^-1 * b^-1 (with! the last one) 393 | 394 | for (uint i = dens.length - 1; i < dens.length; i--) { 395 | dens[i].assign(tmp_2); // all inversed 396 | dens[i].mul_assign(partial_products[i]); // clear lowest terms 397 | tmp_2.mul_assign(dens[i]); 398 | } 399 | 400 | for (uint i = 0; i < nums.length; i++) { 401 | nums[i].mul_assign(dens[i]); 402 | } 403 | 404 | return nums; 405 | } 406 | 407 | function evaluate_vanishing( 408 | uint256 domain_size, 409 | PairingsBn254.Fr memory at 410 | ) internal view returns (PairingsBn254.Fr memory res) { 411 | res = at.pow(domain_size); 412 | res.sub_assign(PairingsBn254.new_fr(1)); 413 | } 414 | 415 | function verify_at_z( 416 | PartialVerifierState memory state, 417 | Proof memory proof, 418 | VerificationKey memory vk 419 | ) internal view returns (bool) { 420 | PairingsBn254.Fr memory lhs = evaluate_vanishing(vk.domain_size, state.z); 421 | assert(lhs.value != 0); // we can not check a polynomial relationship if point `z` is in the domain 422 | lhs.mul_assign(proof.quotient_polynomial_at_z); 423 | 424 | PairingsBn254.Fr memory quotient_challenge = PairingsBn254.new_fr(1); 425 | PairingsBn254.Fr memory rhs = PairingsBn254.copy(proof.linearization_polynomial_at_z); 426 | 427 | // public inputs 428 | PairingsBn254.Fr memory tmp = PairingsBn254.new_fr(0); 429 | for (uint256 i = 0; i < proof.input_values.length; i++) { 430 | tmp.assign(state.cached_lagrange_evals[i]); 431 | tmp.mul_assign(PairingsBn254.new_fr(proof.input_values[i])); 432 | rhs.add_assign(tmp); 433 | } 434 | 435 | quotient_challenge.mul_assign(state.alpha); 436 | 437 | PairingsBn254.Fr memory z_part = PairingsBn254.copy(proof.grand_product_at_z_omega); 438 | for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) { 439 | tmp.assign(proof.permutation_polynomials_at_z[i]); 440 | tmp.mul_assign(state.beta); 441 | tmp.add_assign(state.gamma); 442 | tmp.add_assign(proof.wire_values_at_z[i]); 443 | 444 | z_part.mul_assign(tmp); 445 | } 446 | 447 | tmp.assign(state.gamma); 448 | // we need a wire value of the last polynomial in enumeration 449 | tmp.add_assign(proof.wire_values_at_z[STATE_WIDTH - 1]); 450 | 451 | z_part.mul_assign(tmp); 452 | z_part.mul_assign(quotient_challenge); 453 | 454 | rhs.sub_assign(z_part); 455 | 456 | quotient_challenge.mul_assign(state.alpha); 457 | 458 | tmp.assign(state.cached_lagrange_evals[0]); 459 | tmp.mul_assign(quotient_challenge); 460 | 461 | rhs.sub_assign(tmp); 462 | 463 | return lhs.value == rhs.value; 464 | } 465 | 466 | function reconstruct_d( 467 | PartialVerifierState memory state, 468 | Proof memory proof, 469 | VerificationKey memory vk 470 | ) internal view returns (PairingsBn254.G1Point memory res) { 471 | // we compute what power of v is used as a delinearization factor in batch opening of 472 | // commitments. Let's label W(x) = 1 / (x - z) * 473 | // [ 474 | // t_0(x) + z^n * t_1(x) + z^2n * t_2(x) + z^3n * t_3(x) - t(z) 475 | // + v (r(x) - r(z)) 476 | // + v^{2..5} * (witness(x) - witness(z)) 477 | // + v^(6..8) * (permutation(x) - permutation(z)) 478 | // ] 479 | // W'(x) = 1 / (x - z*omega) * 480 | // [ 481 | // + v^9 (z(x) - z(z*omega)) <- we need this power 482 | // + v^10 * (d(x) - d(z*omega)) 483 | // ] 484 | // 485 | // we pay a little for a few arithmetic operations to not introduce another constant 486 | uint256 power_for_z_omega_opening = 1 + 1 + STATE_WIDTH + STATE_WIDTH - 1; 487 | res = PairingsBn254.copy_g1(vk.selector_commitments[STATE_WIDTH + 1]); 488 | 489 | PairingsBn254.G1Point memory tmp_g1 = PairingsBn254.P1(); 490 | PairingsBn254.Fr memory tmp_fr = PairingsBn254.new_fr(0); 491 | 492 | // addition gates 493 | for (uint256 i = 0; i < STATE_WIDTH; i++) { 494 | tmp_g1 = vk.selector_commitments[i].point_mul(proof.wire_values_at_z[i]); 495 | res.point_add_assign(tmp_g1); 496 | } 497 | 498 | // multiplication gate 499 | tmp_fr.assign(proof.wire_values_at_z[0]); 500 | tmp_fr.mul_assign(proof.wire_values_at_z[1]); 501 | tmp_g1 = vk.selector_commitments[STATE_WIDTH].point_mul(tmp_fr); 502 | res.point_add_assign(tmp_g1); 503 | 504 | // d_next 505 | tmp_g1 = vk.next_step_selector_commitments[0].point_mul(proof.wire_values_at_z_omega[0]); 506 | res.point_add_assign(tmp_g1); 507 | 508 | // z * non_res * beta + gamma + a 509 | PairingsBn254.Fr memory grand_product_part_at_z = PairingsBn254.copy(state.z); 510 | grand_product_part_at_z.mul_assign(state.beta); 511 | grand_product_part_at_z.add_assign(proof.wire_values_at_z[0]); 512 | grand_product_part_at_z.add_assign(state.gamma); 513 | for (uint256 i = 0; i < vk.permutation_non_residues.length; i++) { 514 | tmp_fr.assign(state.z); 515 | tmp_fr.mul_assign(vk.permutation_non_residues[i]); 516 | tmp_fr.mul_assign(state.beta); 517 | tmp_fr.add_assign(state.gamma); 518 | tmp_fr.add_assign(proof.wire_values_at_z[i+1]); 519 | 520 | grand_product_part_at_z.mul_assign(tmp_fr); 521 | } 522 | 523 | grand_product_part_at_z.mul_assign(state.alpha); 524 | 525 | tmp_fr.assign(state.cached_lagrange_evals[0]); 526 | tmp_fr.mul_assign(state.alpha); 527 | tmp_fr.mul_assign(state.alpha); 528 | 529 | grand_product_part_at_z.add_assign(tmp_fr); 530 | 531 | PairingsBn254.Fr memory grand_product_part_at_z_omega = state.v.pow(power_for_z_omega_opening); 532 | grand_product_part_at_z_omega.mul_assign(state.u); 533 | 534 | PairingsBn254.Fr memory last_permutation_part_at_z = PairingsBn254.new_fr(1); 535 | for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) { 536 | tmp_fr.assign(state.beta); 537 | tmp_fr.mul_assign(proof.permutation_polynomials_at_z[i]); 538 | tmp_fr.add_assign(state.gamma); 539 | tmp_fr.add_assign(proof.wire_values_at_z[i]); 540 | 541 | last_permutation_part_at_z.mul_assign(tmp_fr); 542 | } 543 | 544 | last_permutation_part_at_z.mul_assign(state.beta); 545 | last_permutation_part_at_z.mul_assign(proof.grand_product_at_z_omega); 546 | last_permutation_part_at_z.mul_assign(state.alpha); 547 | 548 | // add to the linearization 549 | tmp_g1 = proof.grand_product_commitment.point_mul(grand_product_part_at_z); 550 | tmp_g1.point_sub_assign(vk.permutation_commitments[STATE_WIDTH - 1].point_mul(last_permutation_part_at_z)); 551 | 552 | res.point_add_assign(tmp_g1); 553 | res.point_mul_assign(state.v); 554 | 555 | res.point_add_assign(proof.grand_product_commitment.point_mul(grand_product_part_at_z_omega)); 556 | } 557 | 558 | function verify_commitments( 559 | PartialVerifierState memory state, 560 | Proof memory proof, 561 | VerificationKey memory vk 562 | ) internal view returns (bool) { 563 | PairingsBn254.G1Point memory d = reconstruct_d(state, proof, vk); 564 | 565 | PairingsBn254.Fr memory z_in_domain_size = state.z.pow(vk.domain_size); 566 | 567 | PairingsBn254.G1Point memory tmp_g1 = PairingsBn254.P1(); 568 | 569 | PairingsBn254.Fr memory aggregation_challenge = PairingsBn254.new_fr(1); 570 | 571 | PairingsBn254.G1Point memory commitment_aggregation = PairingsBn254.copy_g1(proof.quotient_poly_commitments[0]); 572 | PairingsBn254.Fr memory tmp_fr = PairingsBn254.new_fr(1); 573 | for (uint i = 1; i < proof.quotient_poly_commitments.length; i++) { 574 | tmp_fr.mul_assign(z_in_domain_size); 575 | tmp_g1 = proof.quotient_poly_commitments[i].point_mul(tmp_fr); 576 | commitment_aggregation.point_add_assign(tmp_g1); 577 | } 578 | 579 | aggregation_challenge.mul_assign(state.v); 580 | commitment_aggregation.point_add_assign(d); 581 | 582 | for (uint i = 0; i < proof.wire_commitments.length; i++) { 583 | aggregation_challenge.mul_assign(state.v); 584 | tmp_g1 = proof.wire_commitments[i].point_mul(aggregation_challenge); 585 | commitment_aggregation.point_add_assign(tmp_g1); 586 | } 587 | 588 | for (uint i = 0; i < vk.permutation_commitments.length - 1; i++) { 589 | aggregation_challenge.mul_assign(state.v); 590 | tmp_g1 = vk.permutation_commitments[i].point_mul(aggregation_challenge); 591 | commitment_aggregation.point_add_assign(tmp_g1); 592 | } 593 | 594 | aggregation_challenge.mul_assign(state.v); 595 | 596 | aggregation_challenge.mul_assign(state.v); 597 | 598 | tmp_fr.assign(aggregation_challenge); 599 | tmp_fr.mul_assign(state.u); 600 | tmp_g1 = proof.wire_commitments[STATE_WIDTH - 1].point_mul(tmp_fr); 601 | commitment_aggregation.point_add_assign(tmp_g1); 602 | 603 | // collect opening values 604 | aggregation_challenge = PairingsBn254.new_fr(1); 605 | 606 | PairingsBn254.Fr memory aggregated_value = PairingsBn254.copy(proof.quotient_polynomial_at_z); 607 | 608 | aggregation_challenge.mul_assign(state.v); 609 | 610 | tmp_fr.assign(proof.linearization_polynomial_at_z); 611 | tmp_fr.mul_assign(aggregation_challenge); 612 | aggregated_value.add_assign(tmp_fr); 613 | 614 | for (uint i = 0; i < proof.wire_values_at_z.length; i++) { 615 | aggregation_challenge.mul_assign(state.v); 616 | 617 | tmp_fr.assign(proof.wire_values_at_z[i]); 618 | tmp_fr.mul_assign(aggregation_challenge); 619 | aggregated_value.add_assign(tmp_fr); 620 | } 621 | 622 | for (uint i = 0; i < proof.permutation_polynomials_at_z.length; i++) { 623 | aggregation_challenge.mul_assign(state.v); 624 | 625 | tmp_fr.assign(proof.permutation_polynomials_at_z[i]); 626 | tmp_fr.mul_assign(aggregation_challenge); 627 | aggregated_value.add_assign(tmp_fr); 628 | } 629 | 630 | aggregation_challenge.mul_assign(state.v); 631 | 632 | tmp_fr.assign(proof.grand_product_at_z_omega); 633 | tmp_fr.mul_assign(aggregation_challenge); 634 | tmp_fr.mul_assign(state.u); 635 | aggregated_value.add_assign(tmp_fr); 636 | 637 | aggregation_challenge.mul_assign(state.v); 638 | 639 | tmp_fr.assign(proof.wire_values_at_z_omega[0]); 640 | tmp_fr.mul_assign(aggregation_challenge); 641 | tmp_fr.mul_assign(state.u); 642 | aggregated_value.add_assign(tmp_fr); 643 | 644 | commitment_aggregation.point_sub_assign(PairingsBn254.P1().point_mul(aggregated_value)); 645 | 646 | PairingsBn254.G1Point memory pair_with_generator = commitment_aggregation; 647 | pair_with_generator.point_add_assign(proof.opening_at_z_proof.point_mul(state.z)); 648 | 649 | tmp_fr.assign(state.z); 650 | tmp_fr.mul_assign(vk.omega); 651 | tmp_fr.mul_assign(state.u); 652 | pair_with_generator.point_add_assign(proof.opening_at_z_omega_proof.point_mul(tmp_fr)); 653 | 654 | PairingsBn254.G1Point memory pair_with_x = proof.opening_at_z_omega_proof.point_mul(state.u); 655 | pair_with_x.point_add_assign(proof.opening_at_z_proof); 656 | pair_with_x.negate(); 657 | 658 | return PairingsBn254.pairingProd2(pair_with_generator, PairingsBn254.P2(), pair_with_x, vk.g2_x); 659 | } 660 | 661 | function verify_initial( 662 | PartialVerifierState memory state, 663 | Proof memory proof, 664 | VerificationKey memory vk 665 | ) internal view returns (bool) { 666 | require(proof.input_values.length == vk.num_inputs); 667 | require(vk.num_inputs >= 1); 668 | TranscriptLibrary.Transcript memory transcript = TranscriptLibrary.new_transcript(); 669 | for (uint256 i = 0; i < vk.num_inputs; i++) { 670 | transcript.update_with_u256(proof.input_values[i]); 671 | } 672 | 673 | for (uint256 i = 0; i < proof.wire_commitments.length; i++) { 674 | transcript.update_with_g1(proof.wire_commitments[i]); 675 | } 676 | 677 | state.beta = transcript.get_challenge(); 678 | state.gamma = transcript.get_challenge(); 679 | 680 | transcript.update_with_g1(proof.grand_product_commitment); 681 | state.alpha = transcript.get_challenge(); 682 | 683 | for (uint256 i = 0; i < proof.quotient_poly_commitments.length; i++) { 684 | transcript.update_with_g1(proof.quotient_poly_commitments[i]); 685 | } 686 | 687 | state.z = transcript.get_challenge(); 688 | 689 | uint256[] memory lagrange_poly_numbers = new uint256[](vk.num_inputs); 690 | for (uint256 i = 0; i < lagrange_poly_numbers.length; i++) { 691 | lagrange_poly_numbers[i] = i; 692 | } 693 | 694 | state.cached_lagrange_evals = batch_evaluate_lagrange_poly_out_of_domain( 695 | lagrange_poly_numbers, 696 | vk.domain_size, 697 | vk.omega, state.z 698 | ); 699 | 700 | bool valid = verify_at_z(state, proof, vk); 701 | 702 | if (valid == false) { 703 | return false; 704 | } 705 | 706 | for (uint256 i = 0; i < proof.wire_values_at_z.length; i++) { 707 | transcript.update_with_fr(proof.wire_values_at_z[i]); 708 | } 709 | 710 | for (uint256 i = 0; i < proof.wire_values_at_z_omega.length; i++) { 711 | transcript.update_with_fr(proof.wire_values_at_z_omega[i]); 712 | } 713 | 714 | for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) { 715 | transcript.update_with_fr(proof.permutation_polynomials_at_z[i]); 716 | } 717 | 718 | transcript.update_with_fr(proof.quotient_polynomial_at_z); 719 | transcript.update_with_fr(proof.linearization_polynomial_at_z); 720 | 721 | state.v = transcript.get_challenge(); 722 | transcript.update_with_g1(proof.opening_at_z_proof); 723 | transcript.update_with_g1(proof.opening_at_z_omega_proof); 724 | state.u = transcript.get_challenge(); 725 | 726 | return true; 727 | } 728 | 729 | // This verifier is for a PLONK with a state width 4 730 | // and main gate equation 731 | // q_a(X) * a(X) + 732 | // q_b(X) * b(X) + 733 | // q_c(X) * c(X) + 734 | // q_d(X) * d(X) + 735 | // q_m(X) * a(X) * b(X) + 736 | // q_constants(X)+ 737 | // q_d_next(X) * d(X*omega) 738 | // where q_{}(X) are selectors a, b, c, d - state (witness) polynomials 739 | // q_d_next(X) "peeks" into the next row of the trace, so it takes 740 | // the same d(X) polynomial, but shifted 741 | 742 | function verify(Proof memory proof, VerificationKey memory vk) internal view returns (bool) { 743 | PartialVerifierState memory state; 744 | 745 | bool valid = verify_initial(state, proof, vk); 746 | 747 | if (valid == false) { 748 | return false; 749 | } 750 | 751 | valid = verify_commitments(state, proof, vk); 752 | 753 | return valid; 754 | } 755 | } 756 | 757 | contract ConcreteVerifier is Plonk4VerifierWithAccessToDNext { 758 | function get_verification_key() internal pure returns(VerificationKey memory vk) { 759 | vk.domain_size = 4194304; 760 | vk.num_inputs = 1; 761 | vk.omega = PairingsBn254.new_fr(0x18c95f1ae6514e11a1b30fd7923947c5ffcec5347f16e91b4dd654168326bede); 762 | vk.selector_commitments[0] = PairingsBn254.new_g1( 763 | 0x2f702f46a651a9b388b5a908babecccc48e59306c80a75c2855ffe53ce1b60e7, 764 | 0x278012543c718d110a97a29cf286c52330f9b780a57043cec08f36895309e4f1 765 | ); 766 | vk.selector_commitments[1] = PairingsBn254.new_g1( 767 | 0x305a8728721fad81716a0696f9afcde4f73211c108078a8b83f531d56456f7b1, 768 | 0x05a1a823893642cf71ca251eaa7f9d7f1fe70ff2399b9ad84aa5a6e7b9419a4f 769 | ); 770 | vk.selector_commitments[2] = PairingsBn254.new_g1( 771 | 0x178ddfc4b5846bda8dcdc8a17bae74dbbc592a983de5b3b697e11b253f8a163b, 772 | 0x2557ec9521f6e4ad15ef940cf76632a3cd4acc43c1534806804ee82b2ada918e 773 | ); 774 | vk.selector_commitments[3] = PairingsBn254.new_g1( 775 | 0x2892b4b8f0c46568d4c561e5b8b8566bd4377fdb12633f7f3c3f92cac610f896, 776 | 0x2156898a3fa6eac08492441a9bb4a5a2db37aa392a10f034ae32bdfd2a17db45 777 | ); 778 | vk.selector_commitments[4] = PairingsBn254.new_g1( 779 | 0x11e132a7906d00e1e391b60c35dbcbf41f2dca61ba4e0c863d3bcd3c9cd34c4a, 780 | 0x12e44baa9d800e085a5c6c5cae1f3e5b043327d8a12388c8c525ca942c0eef86 781 | ); 782 | vk.selector_commitments[5] = PairingsBn254.new_g1( 783 | 0x19c2f274c90b4fd99f74966980bdf7230437dc53fde5e3a1be30242566ff4db7, 784 | 0x00e4105b033a7b6e2d1628a7949d9f14fb66421706cae56bef2c69b9d49f98c9 785 | ); 786 | 787 | // we only have access to value of the d(x) witness polynomial on the next 788 | // trace step, so we only need one element here and deal with it in other places 789 | // by having this in mind 790 | vk.next_step_selector_commitments[0] = PairingsBn254.new_g1( 791 | 0x0676db98c4418f1a4f659a76e16b04a7c297df55250824a64952aaa0093070a0, 792 | 0x1eb4f65fa2a9992c2465ceb19f42b030ce21b8fe006ace9b1262091c3e5d7c11 793 | ); 794 | 795 | vk.permutation_commitments[0] = PairingsBn254.new_g1( 796 | 0x2f4479997d6eca5143a476d491fecaeacec4b1422087ec8428e97e8127bdde19, 797 | 0x07eb7a6bd6954fcb75e65304b75bcd732003caec057f444308b02d20802d291c 798 | ); 799 | vk.permutation_commitments[1] = PairingsBn254.new_g1( 800 | 0x1629c2389d1008a4c2f806c5a853a003f7b7a7c45fcb869cc87c20d94a90bf3e, 801 | 0x05ac17be842eb49f69711cb722a289f0c3cacb807e01cb17795bdefc92c5a99f 802 | ); 803 | vk.permutation_commitments[2] = PairingsBn254.new_g1( 804 | 0x28afc12a8b5ff08374e6ef6494b09161ac089c06a161983ac621f1ed4d923b54, 805 | 0x04da5a500aa46e058f2d64c62c713382c6c991b0009106b15e0ffec20f9c58a9 806 | ); 807 | vk.permutation_commitments[3] = PairingsBn254.new_g1( 808 | 0x264adcb54404f3b255ad81b481edd4193f80decaa1b6fea28bbf5f29c36b1cc1, 809 | 0x059b0a160706cda2cbc8e6a0d62d924e33a8a22aa8be8c66f70e1d0dbb88c470 810 | ); 811 | 812 | vk.permutation_non_residues[0] = PairingsBn254.new_fr( 813 | 0x0000000000000000000000000000000000000000000000000000000000000005 814 | ); 815 | vk.permutation_non_residues[1] = PairingsBn254.new_fr( 816 | 0x0000000000000000000000000000000000000000000000000000000000000007 817 | ); 818 | vk.permutation_non_residues[2] = PairingsBn254.new_fr( 819 | 0x000000000000000000000000000000000000000000000000000000000000000a 820 | ); 821 | 822 | vk.g2_x = PairingsBn254.new_g2( 823 | [0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1, 824 | 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0], 825 | [0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4, 826 | 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55] 827 | ); 828 | } 829 | 830 | 831 | function deserialize_proof( 832 | uint256 expected_inputs, 833 | uint256[] memory public_inputs, 834 | uint256[] memory serialized_proof 835 | ) internal pure returns(Proof memory proof) { 836 | assert(expected_inputs == public_inputs.length); 837 | proof.input_values = new uint256[](expected_inputs); 838 | for (uint256 i = 0; i < expected_inputs; i++) { 839 | proof.input_values[i] = public_inputs[i]; 840 | } 841 | 842 | uint256 j = 0; 843 | for (uint256 i = 0; i < STATE_WIDTH; i++) { 844 | proof.wire_commitments[i] = PairingsBn254.new_g1( 845 | serialized_proof[j], 846 | serialized_proof[j+1] 847 | ); 848 | 849 | j += 2; 850 | } 851 | 852 | proof.grand_product_commitment = PairingsBn254.new_g1( 853 | serialized_proof[j], 854 | serialized_proof[j+1] 855 | ); 856 | j += 2; 857 | 858 | for (uint256 i = 0; i < STATE_WIDTH; i++) { 859 | proof.quotient_poly_commitments[i] = PairingsBn254.new_g1( 860 | serialized_proof[j], 861 | serialized_proof[j+1] 862 | ); 863 | 864 | j += 2; 865 | } 866 | 867 | for (uint256 i = 0; i < STATE_WIDTH; i++) { 868 | proof.wire_values_at_z[i] = PairingsBn254.new_fr( 869 | serialized_proof[j] 870 | ); 871 | 872 | j += 1; 873 | } 874 | 875 | for (uint256 i = 0; i < proof.wire_values_at_z_omega.length; i++) { 876 | proof.wire_values_at_z_omega[i] = PairingsBn254.new_fr( 877 | serialized_proof[j] 878 | ); 879 | 880 | j += 1; 881 | } 882 | 883 | proof.grand_product_at_z_omega = PairingsBn254.new_fr( 884 | serialized_proof[j] 885 | ); 886 | 887 | j += 1; 888 | 889 | proof.quotient_polynomial_at_z = PairingsBn254.new_fr( 890 | serialized_proof[j] 891 | ); 892 | 893 | j += 1; 894 | 895 | proof.linearization_polynomial_at_z = PairingsBn254.new_fr( 896 | serialized_proof[j] 897 | ); 898 | 899 | j += 1; 900 | 901 | for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) { 902 | proof.permutation_polynomials_at_z[i] = PairingsBn254.new_fr( 903 | serialized_proof[j] 904 | ); 905 | 906 | j += 1; 907 | } 908 | 909 | proof.opening_at_z_proof = PairingsBn254.new_g1( 910 | serialized_proof[j], 911 | serialized_proof[j+1] 912 | ); 913 | j += 2; 914 | 915 | proof.opening_at_z_omega_proof = PairingsBn254.new_g1( 916 | serialized_proof[j], 917 | serialized_proof[j+1] 918 | ); 919 | 920 | j += 2; 921 | assert(j == serialized_proof.length); 922 | } 923 | 924 | function verify( 925 | uint256[] memory public_inputs, 926 | uint256[] memory serialized_proof 927 | ) public view returns (bool) { 928 | VerificationKey memory vk = get_verification_key(); 929 | uint256 expected_inputs = vk.num_inputs; 930 | 931 | Proof memory proof = deserialize_proof(expected_inputs, public_inputs, serialized_proof); 932 | 933 | bool valid = verify(proof, vk); 934 | 935 | return valid; 936 | } 937 | } -------------------------------------------------------------------------------- /bellman_vk_codegen/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | verifier.sol 3 | xor.sol 4 | test.sol 5 | *.key 6 | *.proof -------------------------------------------------------------------------------- /bellman_vk_codegen/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "aho-corasick" 5 | version = "0.7.10" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" 8 | dependencies = [ 9 | "memchr", 10 | ] 11 | 12 | [[package]] 13 | name = "arrayref" 14 | version = "0.3.6" 15 | source = "registry+https://github.com/rust-lang/crates.io-index" 16 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 17 | 18 | [[package]] 19 | name = "arrayvec" 20 | version = "0.4.12" 21 | source = "registry+https://github.com/rust-lang/crates.io-index" 22 | checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" 23 | dependencies = [ 24 | "nodrop", 25 | ] 26 | 27 | [[package]] 28 | name = "arrayvec" 29 | version = "0.5.1" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" 32 | 33 | [[package]] 34 | name = "autocfg" 35 | version = "0.1.7" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" 38 | 39 | [[package]] 40 | name = "autocfg" 41 | version = "1.0.0" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" 44 | 45 | [[package]] 46 | name = "base64" 47 | version = "0.10.1" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" 50 | dependencies = [ 51 | "byteorder", 52 | ] 53 | 54 | [[package]] 55 | name = "bellman_ce" 56 | version = "0.3.1" 57 | source = "git+https://github.com/matter-labs/bellman?branch=plonk_release#b6df3ab8e585b6a28075eef1c048d6c8930c3fc9" 58 | dependencies = [ 59 | "bit-vec", 60 | "blake2s_const", 61 | "blake2s_simd", 62 | "byteorder", 63 | "cfg-if", 64 | "crossbeam", 65 | "futures", 66 | "futures-cpupool", 67 | "hex", 68 | "lazy_static", 69 | "num_cpus", 70 | "pairing_ce", 71 | "rand 0.4.6", 72 | "tiny-keccak", 73 | ] 74 | 75 | [[package]] 76 | name = "bellman_vk_codegen" 77 | version = "0.1.0" 78 | dependencies = [ 79 | "bellman_ce", 80 | "handlebars", 81 | "hex", 82 | "serde_json", 83 | "web3", 84 | ] 85 | 86 | [[package]] 87 | name = "bit-vec" 88 | version = "0.4.4" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f" 91 | 92 | [[package]] 93 | name = "bitflags" 94 | version = "1.2.1" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 97 | 98 | [[package]] 99 | name = "blake2s_const" 100 | version = "0.6.0" 101 | source = "git+https://github.com/matter-labs/bellman?branch=plonk_release#b6df3ab8e585b6a28075eef1c048d6c8930c3fc9" 102 | dependencies = [ 103 | "arrayref", 104 | "arrayvec 0.5.1", 105 | "constant_time_eq", 106 | ] 107 | 108 | [[package]] 109 | name = "blake2s_simd" 110 | version = "0.5.10" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "ab9e07352b829279624ceb7c64adb4f585dacdb81d35cafae81139ccd617cf44" 113 | dependencies = [ 114 | "arrayref", 115 | "arrayvec 0.5.1", 116 | "constant_time_eq", 117 | ] 118 | 119 | [[package]] 120 | name = "block-buffer" 121 | version = "0.7.3" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" 124 | dependencies = [ 125 | "block-padding", 126 | "byte-tools", 127 | "byteorder", 128 | "generic-array", 129 | ] 130 | 131 | [[package]] 132 | name = "block-padding" 133 | version = "0.1.5" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" 136 | dependencies = [ 137 | "byte-tools", 138 | ] 139 | 140 | [[package]] 141 | name = "byte-tools" 142 | version = "0.3.1" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" 145 | 146 | [[package]] 147 | name = "byteorder" 148 | version = "1.3.4" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" 151 | 152 | [[package]] 153 | name = "cfg-if" 154 | version = "0.1.10" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 157 | 158 | [[package]] 159 | name = "cloudabi" 160 | version = "0.0.3" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 163 | dependencies = [ 164 | "bitflags", 165 | ] 166 | 167 | [[package]] 168 | name = "constant_time_eq" 169 | version = "0.1.5" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" 172 | 173 | [[package]] 174 | name = "crossbeam" 175 | version = "0.7.3" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" 178 | dependencies = [ 179 | "cfg-if", 180 | "crossbeam-channel", 181 | "crossbeam-deque", 182 | "crossbeam-epoch", 183 | "crossbeam-queue", 184 | "crossbeam-utils", 185 | ] 186 | 187 | [[package]] 188 | name = "crossbeam-channel" 189 | version = "0.4.2" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061" 192 | dependencies = [ 193 | "crossbeam-utils", 194 | "maybe-uninit", 195 | ] 196 | 197 | [[package]] 198 | name = "crossbeam-deque" 199 | version = "0.7.3" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" 202 | dependencies = [ 203 | "crossbeam-epoch", 204 | "crossbeam-utils", 205 | "maybe-uninit", 206 | ] 207 | 208 | [[package]] 209 | name = "crossbeam-epoch" 210 | version = "0.8.2" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" 213 | dependencies = [ 214 | "autocfg 1.0.0", 215 | "cfg-if", 216 | "crossbeam-utils", 217 | "lazy_static", 218 | "maybe-uninit", 219 | "memoffset", 220 | "scopeguard", 221 | ] 222 | 223 | [[package]] 224 | name = "crossbeam-queue" 225 | version = "0.2.1" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" 228 | dependencies = [ 229 | "cfg-if", 230 | "crossbeam-utils", 231 | ] 232 | 233 | [[package]] 234 | name = "crossbeam-utils" 235 | version = "0.7.2" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 238 | dependencies = [ 239 | "autocfg 1.0.0", 240 | "cfg-if", 241 | "lazy_static", 242 | ] 243 | 244 | [[package]] 245 | name = "crunchy" 246 | version = "0.2.2" 247 | source = "registry+https://github.com/rust-lang/crates.io-index" 248 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 249 | 250 | [[package]] 251 | name = "derive_more" 252 | version = "0.15.0" 253 | source = "registry+https://github.com/rust-lang/crates.io-index" 254 | checksum = "7a141330240c921ec6d074a3e188a7c7ef95668bb95e7d44fa0e5778ec2a7afe" 255 | dependencies = [ 256 | "lazy_static", 257 | "proc-macro2 0.4.30", 258 | "quote 0.6.13", 259 | "regex", 260 | "rustc_version", 261 | "syn 0.15.44", 262 | ] 263 | 264 | [[package]] 265 | name = "digest" 266 | version = "0.8.1" 267 | source = "registry+https://github.com/rust-lang/crates.io-index" 268 | checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" 269 | dependencies = [ 270 | "generic-array", 271 | ] 272 | 273 | [[package]] 274 | name = "error-chain" 275 | version = "0.12.2" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "d371106cc88ffdfb1eabd7111e432da544f16f3e2d7bf1dfe8bf575f1df045cd" 278 | dependencies = [ 279 | "version_check", 280 | ] 281 | 282 | [[package]] 283 | name = "ethabi" 284 | version = "8.0.1" 285 | source = "registry+https://github.com/rust-lang/crates.io-index" 286 | checksum = "ebdeeea85a6d217b9fcc862906d7e283c047e04114165c433756baf5dce00a6c" 287 | dependencies = [ 288 | "error-chain", 289 | "ethereum-types", 290 | "rustc-hex", 291 | "serde", 292 | "serde_derive", 293 | "serde_json", 294 | "tiny-keccak", 295 | ] 296 | 297 | [[package]] 298 | name = "ethbloom" 299 | version = "0.6.4" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "3932e82d64d347a045208924002930dc105a138995ccdc1479d0f05f0359f17c" 302 | dependencies = [ 303 | "crunchy", 304 | "fixed-hash", 305 | "impl-rlp", 306 | "impl-serde", 307 | "tiny-keccak", 308 | ] 309 | 310 | [[package]] 311 | name = "ethereum-types" 312 | version = "0.6.0" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | checksum = "62d1bc682337e2c5ec98930853674dd2b4bd5d0d246933a9e98e5280f7c76c5f" 315 | dependencies = [ 316 | "ethbloom", 317 | "fixed-hash", 318 | "impl-rlp", 319 | "impl-serde", 320 | "primitive-types", 321 | "uint", 322 | ] 323 | 324 | [[package]] 325 | name = "fake-simd" 326 | version = "0.1.2" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" 329 | 330 | [[package]] 331 | name = "ff_ce" 332 | version = "0.7.1" 333 | source = "git+https://github.com/matter-labs/ff.git?branch=playground#3f6722c07038bb68c0b9a1012cdddd01037aa985" 334 | dependencies = [ 335 | "byteorder", 336 | "ff_derive_ce", 337 | "hex", 338 | "rand 0.4.6", 339 | ] 340 | 341 | [[package]] 342 | name = "ff_derive_ce" 343 | version = "0.6.0" 344 | source = "git+https://github.com/matter-labs/ff.git?branch=playground#3f6722c07038bb68c0b9a1012cdddd01037aa985" 345 | dependencies = [ 346 | "num-bigint", 347 | "num-integer", 348 | "num-traits", 349 | "proc-macro2 1.0.9", 350 | "quote 1.0.3", 351 | "syn 1.0.17", 352 | ] 353 | 354 | [[package]] 355 | name = "fixed-hash" 356 | version = "0.3.2" 357 | source = "registry+https://github.com/rust-lang/crates.io-index" 358 | checksum = "d1a683d1234507e4f3bf2736eeddf0de1dc65996dc0164d57eba0a74bcf29489" 359 | dependencies = [ 360 | "byteorder", 361 | "heapsize", 362 | "rand 0.5.6", 363 | "rustc-hex", 364 | "static_assertions", 365 | ] 366 | 367 | [[package]] 368 | name = "fuchsia-cprng" 369 | version = "0.1.1" 370 | source = "registry+https://github.com/rust-lang/crates.io-index" 371 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 372 | 373 | [[package]] 374 | name = "futures" 375 | version = "0.1.29" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" 378 | 379 | [[package]] 380 | name = "futures-cpupool" 381 | version = "0.1.8" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" 384 | dependencies = [ 385 | "futures", 386 | "num_cpus", 387 | ] 388 | 389 | [[package]] 390 | name = "generic-array" 391 | version = "0.12.3" 392 | source = "registry+https://github.com/rust-lang/crates.io-index" 393 | checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" 394 | dependencies = [ 395 | "typenum", 396 | ] 397 | 398 | [[package]] 399 | name = "handlebars" 400 | version = "3.0.1" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "ba758d094d31274eb49d15da6f326b96bf3185239a6359bf684f3d5321148900" 403 | dependencies = [ 404 | "log", 405 | "pest", 406 | "pest_derive", 407 | "quick-error", 408 | "serde", 409 | "serde_json", 410 | ] 411 | 412 | [[package]] 413 | name = "heapsize" 414 | version = "0.4.2" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "1679e6ea370dee694f91f1dc469bf94cf8f52051d147aec3e1f9497c6fc22461" 417 | dependencies = [ 418 | "winapi", 419 | ] 420 | 421 | [[package]] 422 | name = "hermit-abi" 423 | version = "0.1.8" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8" 426 | dependencies = [ 427 | "libc", 428 | ] 429 | 430 | [[package]] 431 | name = "hex" 432 | version = "0.4.2" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" 435 | 436 | [[package]] 437 | name = "idna" 438 | version = "0.1.5" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" 441 | dependencies = [ 442 | "matches", 443 | "unicode-bidi", 444 | "unicode-normalization", 445 | ] 446 | 447 | [[package]] 448 | name = "impl-codec" 449 | version = "0.2.0" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | checksum = "d2050d823639fbeae26b2b5ba09aca8907793117324858070ade0673c49f793b" 452 | dependencies = [ 453 | "parity-codec", 454 | ] 455 | 456 | [[package]] 457 | name = "impl-rlp" 458 | version = "0.2.1" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "8f7a72f11830b52333f36e3b09a288333888bf54380fd0ac0790a3c31ab0f3c5" 461 | dependencies = [ 462 | "rlp", 463 | ] 464 | 465 | [[package]] 466 | name = "impl-serde" 467 | version = "0.2.3" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "58e3cae7e99c7ff5a995da2cf78dd0a5383740eda71d98cf7b1910c301ac69b8" 470 | dependencies = [ 471 | "serde", 472 | ] 473 | 474 | [[package]] 475 | name = "itoa" 476 | version = "0.4.5" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" 479 | 480 | [[package]] 481 | name = "jsonrpc-core" 482 | version = "11.0.0" 483 | source = "registry+https://github.com/rust-lang/crates.io-index" 484 | checksum = "97b83fdc5e0218128d0d270f2f2e7a5ea716f3240c8518a58bc89e6716ba8581" 485 | dependencies = [ 486 | "futures", 487 | "log", 488 | "serde", 489 | "serde_derive", 490 | "serde_json", 491 | ] 492 | 493 | [[package]] 494 | name = "lazy_static" 495 | version = "1.4.0" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 498 | 499 | [[package]] 500 | name = "libc" 501 | version = "0.2.68" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" 504 | 505 | [[package]] 506 | name = "lock_api" 507 | version = "0.2.0" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" 510 | dependencies = [ 511 | "scopeguard", 512 | ] 513 | 514 | [[package]] 515 | name = "log" 516 | version = "0.4.8" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 519 | dependencies = [ 520 | "cfg-if", 521 | ] 522 | 523 | [[package]] 524 | name = "maplit" 525 | version = "1.0.2" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" 528 | 529 | [[package]] 530 | name = "matches" 531 | version = "0.1.8" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 534 | 535 | [[package]] 536 | name = "maybe-uninit" 537 | version = "2.0.0" 538 | source = "registry+https://github.com/rust-lang/crates.io-index" 539 | checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" 540 | 541 | [[package]] 542 | name = "memchr" 543 | version = "2.3.3" 544 | source = "registry+https://github.com/rust-lang/crates.io-index" 545 | checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" 546 | 547 | [[package]] 548 | name = "memoffset" 549 | version = "0.5.4" 550 | source = "registry+https://github.com/rust-lang/crates.io-index" 551 | checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" 552 | dependencies = [ 553 | "autocfg 1.0.0", 554 | ] 555 | 556 | [[package]] 557 | name = "nodrop" 558 | version = "0.1.14" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" 561 | 562 | [[package]] 563 | name = "num-bigint" 564 | version = "0.2.6" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" 567 | dependencies = [ 568 | "autocfg 1.0.0", 569 | "num-integer", 570 | "num-traits", 571 | ] 572 | 573 | [[package]] 574 | name = "num-integer" 575 | version = "0.1.42" 576 | source = "registry+https://github.com/rust-lang/crates.io-index" 577 | checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" 578 | dependencies = [ 579 | "autocfg 1.0.0", 580 | "num-traits", 581 | ] 582 | 583 | [[package]] 584 | name = "num-traits" 585 | version = "0.2.11" 586 | source = "registry+https://github.com/rust-lang/crates.io-index" 587 | checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" 588 | dependencies = [ 589 | "autocfg 1.0.0", 590 | ] 591 | 592 | [[package]] 593 | name = "num_cpus" 594 | version = "1.12.0" 595 | source = "registry+https://github.com/rust-lang/crates.io-index" 596 | checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" 597 | dependencies = [ 598 | "hermit-abi", 599 | "libc", 600 | ] 601 | 602 | [[package]] 603 | name = "opaque-debug" 604 | version = "0.2.3" 605 | source = "registry+https://github.com/rust-lang/crates.io-index" 606 | checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" 607 | 608 | [[package]] 609 | name = "pairing_ce" 610 | version = "0.20.0" 611 | source = "git+https://github.com/matter-labs/pairing.git?branch=affine-ops#af828bd2fb1c83c49fe202a0b2b3cc5d177d4d18" 612 | dependencies = [ 613 | "byteorder", 614 | "ff_ce", 615 | "rand 0.4.6", 616 | ] 617 | 618 | [[package]] 619 | name = "parity-codec" 620 | version = "3.5.4" 621 | source = "registry+https://github.com/rust-lang/crates.io-index" 622 | checksum = "2b9df1283109f542d8852cd6b30e9341acc2137481eb6157d2e62af68b0afec9" 623 | dependencies = [ 624 | "arrayvec 0.4.12", 625 | "serde", 626 | ] 627 | 628 | [[package]] 629 | name = "parking_lot" 630 | version = "0.8.0" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" 633 | dependencies = [ 634 | "lock_api", 635 | "parking_lot_core", 636 | "rustc_version", 637 | ] 638 | 639 | [[package]] 640 | name = "parking_lot_core" 641 | version = "0.5.0" 642 | source = "registry+https://github.com/rust-lang/crates.io-index" 643 | checksum = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" 644 | dependencies = [ 645 | "cfg-if", 646 | "cloudabi", 647 | "libc", 648 | "rand 0.6.5", 649 | "redox_syscall", 650 | "rustc_version", 651 | "smallvec 0.6.13", 652 | "winapi", 653 | ] 654 | 655 | [[package]] 656 | name = "percent-encoding" 657 | version = "1.0.1" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" 660 | 661 | [[package]] 662 | name = "pest" 663 | version = "2.1.3" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" 666 | dependencies = [ 667 | "ucd-trie", 668 | ] 669 | 670 | [[package]] 671 | name = "pest_derive" 672 | version = "2.1.0" 673 | source = "registry+https://github.com/rust-lang/crates.io-index" 674 | checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" 675 | dependencies = [ 676 | "pest", 677 | "pest_generator", 678 | ] 679 | 680 | [[package]] 681 | name = "pest_generator" 682 | version = "2.1.3" 683 | source = "registry+https://github.com/rust-lang/crates.io-index" 684 | checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" 685 | dependencies = [ 686 | "pest", 687 | "pest_meta", 688 | "proc-macro2 1.0.9", 689 | "quote 1.0.3", 690 | "syn 1.0.17", 691 | ] 692 | 693 | [[package]] 694 | name = "pest_meta" 695 | version = "2.1.3" 696 | source = "registry+https://github.com/rust-lang/crates.io-index" 697 | checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" 698 | dependencies = [ 699 | "maplit", 700 | "pest", 701 | "sha-1", 702 | ] 703 | 704 | [[package]] 705 | name = "primitive-types" 706 | version = "0.3.0" 707 | source = "registry+https://github.com/rust-lang/crates.io-index" 708 | checksum = "2288eb2a39386c4bc817974cc413afe173010dc80e470fcb1e9a35580869f024" 709 | dependencies = [ 710 | "fixed-hash", 711 | "impl-codec", 712 | "impl-rlp", 713 | "impl-serde", 714 | "uint", 715 | ] 716 | 717 | [[package]] 718 | name = "proc-macro2" 719 | version = "0.4.30" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" 722 | dependencies = [ 723 | "unicode-xid 0.1.0", 724 | ] 725 | 726 | [[package]] 727 | name = "proc-macro2" 728 | version = "1.0.9" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" 731 | dependencies = [ 732 | "unicode-xid 0.2.0", 733 | ] 734 | 735 | [[package]] 736 | name = "quick-error" 737 | version = "1.2.3" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 740 | 741 | [[package]] 742 | name = "quote" 743 | version = "0.6.13" 744 | source = "registry+https://github.com/rust-lang/crates.io-index" 745 | checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" 746 | dependencies = [ 747 | "proc-macro2 0.4.30", 748 | ] 749 | 750 | [[package]] 751 | name = "quote" 752 | version = "1.0.3" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" 755 | dependencies = [ 756 | "proc-macro2 1.0.9", 757 | ] 758 | 759 | [[package]] 760 | name = "rand" 761 | version = "0.4.6" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" 764 | dependencies = [ 765 | "fuchsia-cprng", 766 | "libc", 767 | "rand_core 0.3.1", 768 | "rdrand", 769 | "winapi", 770 | ] 771 | 772 | [[package]] 773 | name = "rand" 774 | version = "0.5.6" 775 | source = "registry+https://github.com/rust-lang/crates.io-index" 776 | checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" 777 | dependencies = [ 778 | "cloudabi", 779 | "fuchsia-cprng", 780 | "libc", 781 | "rand_core 0.3.1", 782 | "winapi", 783 | ] 784 | 785 | [[package]] 786 | name = "rand" 787 | version = "0.6.5" 788 | source = "registry+https://github.com/rust-lang/crates.io-index" 789 | checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" 790 | dependencies = [ 791 | "autocfg 0.1.7", 792 | "libc", 793 | "rand_chacha", 794 | "rand_core 0.4.2", 795 | "rand_hc", 796 | "rand_isaac", 797 | "rand_jitter", 798 | "rand_os", 799 | "rand_pcg", 800 | "rand_xorshift", 801 | "winapi", 802 | ] 803 | 804 | [[package]] 805 | name = "rand_chacha" 806 | version = "0.1.1" 807 | source = "registry+https://github.com/rust-lang/crates.io-index" 808 | checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" 809 | dependencies = [ 810 | "autocfg 0.1.7", 811 | "rand_core 0.3.1", 812 | ] 813 | 814 | [[package]] 815 | name = "rand_core" 816 | version = "0.3.1" 817 | source = "registry+https://github.com/rust-lang/crates.io-index" 818 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 819 | dependencies = [ 820 | "rand_core 0.4.2", 821 | ] 822 | 823 | [[package]] 824 | name = "rand_core" 825 | version = "0.4.2" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 828 | 829 | [[package]] 830 | name = "rand_hc" 831 | version = "0.1.0" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" 834 | dependencies = [ 835 | "rand_core 0.3.1", 836 | ] 837 | 838 | [[package]] 839 | name = "rand_isaac" 840 | version = "0.1.1" 841 | source = "registry+https://github.com/rust-lang/crates.io-index" 842 | checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" 843 | dependencies = [ 844 | "rand_core 0.3.1", 845 | ] 846 | 847 | [[package]] 848 | name = "rand_jitter" 849 | version = "0.1.4" 850 | source = "registry+https://github.com/rust-lang/crates.io-index" 851 | checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" 852 | dependencies = [ 853 | "libc", 854 | "rand_core 0.4.2", 855 | "winapi", 856 | ] 857 | 858 | [[package]] 859 | name = "rand_os" 860 | version = "0.1.3" 861 | source = "registry+https://github.com/rust-lang/crates.io-index" 862 | checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" 863 | dependencies = [ 864 | "cloudabi", 865 | "fuchsia-cprng", 866 | "libc", 867 | "rand_core 0.4.2", 868 | "rdrand", 869 | "winapi", 870 | ] 871 | 872 | [[package]] 873 | name = "rand_pcg" 874 | version = "0.1.2" 875 | source = "registry+https://github.com/rust-lang/crates.io-index" 876 | checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" 877 | dependencies = [ 878 | "autocfg 0.1.7", 879 | "rand_core 0.4.2", 880 | ] 881 | 882 | [[package]] 883 | name = "rand_xorshift" 884 | version = "0.1.1" 885 | source = "registry+https://github.com/rust-lang/crates.io-index" 886 | checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" 887 | dependencies = [ 888 | "rand_core 0.3.1", 889 | ] 890 | 891 | [[package]] 892 | name = "rdrand" 893 | version = "0.4.0" 894 | source = "registry+https://github.com/rust-lang/crates.io-index" 895 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 896 | dependencies = [ 897 | "rand_core 0.3.1", 898 | ] 899 | 900 | [[package]] 901 | name = "redox_syscall" 902 | version = "0.1.56" 903 | source = "registry+https://github.com/rust-lang/crates.io-index" 904 | checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 905 | 906 | [[package]] 907 | name = "regex" 908 | version = "1.3.5" 909 | source = "registry+https://github.com/rust-lang/crates.io-index" 910 | checksum = "8900ebc1363efa7ea1c399ccc32daed870b4002651e0bed86e72d501ebbe0048" 911 | dependencies = [ 912 | "aho-corasick", 913 | "memchr", 914 | "regex-syntax", 915 | "thread_local", 916 | ] 917 | 918 | [[package]] 919 | name = "regex-syntax" 920 | version = "0.6.17" 921 | source = "registry+https://github.com/rust-lang/crates.io-index" 922 | checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" 923 | 924 | [[package]] 925 | name = "rlp" 926 | version = "0.4.5" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "4a7d3f9bed94764eac15b8f14af59fac420c236adaff743b7bcc88e265cb4345" 929 | dependencies = [ 930 | "rustc-hex", 931 | ] 932 | 933 | [[package]] 934 | name = "rustc-hex" 935 | version = "2.1.0" 936 | source = "registry+https://github.com/rust-lang/crates.io-index" 937 | checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" 938 | 939 | [[package]] 940 | name = "rustc_version" 941 | version = "0.2.3" 942 | source = "registry+https://github.com/rust-lang/crates.io-index" 943 | checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 944 | dependencies = [ 945 | "semver", 946 | ] 947 | 948 | [[package]] 949 | name = "ryu" 950 | version = "1.0.3" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76" 953 | 954 | [[package]] 955 | name = "scopeguard" 956 | version = "1.1.0" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 959 | 960 | [[package]] 961 | name = "semver" 962 | version = "0.9.0" 963 | source = "registry+https://github.com/rust-lang/crates.io-index" 964 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 965 | dependencies = [ 966 | "semver-parser", 967 | ] 968 | 969 | [[package]] 970 | name = "semver-parser" 971 | version = "0.7.0" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 974 | 975 | [[package]] 976 | name = "serde" 977 | version = "1.0.105" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff" 980 | dependencies = [ 981 | "serde_derive", 982 | ] 983 | 984 | [[package]] 985 | name = "serde_derive" 986 | version = "1.0.105" 987 | source = "registry+https://github.com/rust-lang/crates.io-index" 988 | checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" 989 | dependencies = [ 990 | "proc-macro2 1.0.9", 991 | "quote 1.0.3", 992 | "syn 1.0.17", 993 | ] 994 | 995 | [[package]] 996 | name = "serde_json" 997 | version = "1.0.48" 998 | source = "registry+https://github.com/rust-lang/crates.io-index" 999 | checksum = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25" 1000 | dependencies = [ 1001 | "itoa", 1002 | "ryu", 1003 | "serde", 1004 | ] 1005 | 1006 | [[package]] 1007 | name = "sha-1" 1008 | version = "0.8.2" 1009 | source = "registry+https://github.com/rust-lang/crates.io-index" 1010 | checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" 1011 | dependencies = [ 1012 | "block-buffer", 1013 | "digest", 1014 | "fake-simd", 1015 | "opaque-debug", 1016 | ] 1017 | 1018 | [[package]] 1019 | name = "slab" 1020 | version = "0.3.0" 1021 | source = "registry+https://github.com/rust-lang/crates.io-index" 1022 | checksum = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" 1023 | 1024 | [[package]] 1025 | name = "smallvec" 1026 | version = "0.6.13" 1027 | source = "registry+https://github.com/rust-lang/crates.io-index" 1028 | checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" 1029 | dependencies = [ 1030 | "maybe-uninit", 1031 | ] 1032 | 1033 | [[package]] 1034 | name = "smallvec" 1035 | version = "1.2.0" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc" 1038 | 1039 | [[package]] 1040 | name = "static_assertions" 1041 | version = "0.2.5" 1042 | source = "registry+https://github.com/rust-lang/crates.io-index" 1043 | checksum = "c19be23126415861cb3a23e501d34a708f7f9b2183c5252d690941c2e69199d5" 1044 | 1045 | [[package]] 1046 | name = "syn" 1047 | version = "0.15.44" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" 1050 | dependencies = [ 1051 | "proc-macro2 0.4.30", 1052 | "quote 0.6.13", 1053 | "unicode-xid 0.1.0", 1054 | ] 1055 | 1056 | [[package]] 1057 | name = "syn" 1058 | version = "1.0.17" 1059 | source = "registry+https://github.com/rust-lang/crates.io-index" 1060 | checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" 1061 | dependencies = [ 1062 | "proc-macro2 1.0.9", 1063 | "quote 1.0.3", 1064 | "unicode-xid 0.2.0", 1065 | ] 1066 | 1067 | [[package]] 1068 | name = "thread_local" 1069 | version = "1.0.1" 1070 | source = "registry+https://github.com/rust-lang/crates.io-index" 1071 | checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" 1072 | dependencies = [ 1073 | "lazy_static", 1074 | ] 1075 | 1076 | [[package]] 1077 | name = "tiny-keccak" 1078 | version = "1.5.0" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | checksum = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" 1081 | dependencies = [ 1082 | "crunchy", 1083 | ] 1084 | 1085 | [[package]] 1086 | name = "tokio-timer" 1087 | version = "0.1.2" 1088 | source = "registry+https://github.com/rust-lang/crates.io-index" 1089 | checksum = "6131e780037787ff1b3f8aad9da83bca02438b72277850dd6ad0d455e0e20efc" 1090 | dependencies = [ 1091 | "futures", 1092 | "slab", 1093 | ] 1094 | 1095 | [[package]] 1096 | name = "typenum" 1097 | version = "1.11.2" 1098 | source = "registry+https://github.com/rust-lang/crates.io-index" 1099 | checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" 1100 | 1101 | [[package]] 1102 | name = "ucd-trie" 1103 | version = "0.1.3" 1104 | source = "registry+https://github.com/rust-lang/crates.io-index" 1105 | checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" 1106 | 1107 | [[package]] 1108 | name = "uint" 1109 | version = "0.7.1" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "2143cded94692b156c356508d92888acc824db5bffc0b4089732264c6fcf86d4" 1112 | dependencies = [ 1113 | "byteorder", 1114 | "crunchy", 1115 | "heapsize", 1116 | "rustc-hex", 1117 | ] 1118 | 1119 | [[package]] 1120 | name = "unicode-bidi" 1121 | version = "0.3.4" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 1124 | dependencies = [ 1125 | "matches", 1126 | ] 1127 | 1128 | [[package]] 1129 | name = "unicode-normalization" 1130 | version = "0.1.12" 1131 | source = "registry+https://github.com/rust-lang/crates.io-index" 1132 | checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" 1133 | dependencies = [ 1134 | "smallvec 1.2.0", 1135 | ] 1136 | 1137 | [[package]] 1138 | name = "unicode-xid" 1139 | version = "0.1.0" 1140 | source = "registry+https://github.com/rust-lang/crates.io-index" 1141 | checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 1142 | 1143 | [[package]] 1144 | name = "unicode-xid" 1145 | version = "0.2.0" 1146 | source = "registry+https://github.com/rust-lang/crates.io-index" 1147 | checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 1148 | 1149 | [[package]] 1150 | name = "url" 1151 | version = "1.7.2" 1152 | source = "registry+https://github.com/rust-lang/crates.io-index" 1153 | checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" 1154 | dependencies = [ 1155 | "idna", 1156 | "matches", 1157 | "percent-encoding", 1158 | ] 1159 | 1160 | [[package]] 1161 | name = "version_check" 1162 | version = "0.9.1" 1163 | source = "registry+https://github.com/rust-lang/crates.io-index" 1164 | checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" 1165 | 1166 | [[package]] 1167 | name = "web3" 1168 | version = "0.8.0" 1169 | source = "registry+https://github.com/rust-lang/crates.io-index" 1170 | checksum = "076f34ed252d74a8521e3b013254b1a39f94a98f23aae7cfc85cda6e7b395664" 1171 | dependencies = [ 1172 | "arrayvec 0.4.12", 1173 | "base64", 1174 | "derive_more", 1175 | "ethabi", 1176 | "ethereum-types", 1177 | "futures", 1178 | "jsonrpc-core", 1179 | "log", 1180 | "parking_lot", 1181 | "rustc-hex", 1182 | "serde", 1183 | "serde_json", 1184 | "tokio-timer", 1185 | "url", 1186 | ] 1187 | 1188 | [[package]] 1189 | name = "winapi" 1190 | version = "0.3.8" 1191 | source = "registry+https://github.com/rust-lang/crates.io-index" 1192 | checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 1193 | dependencies = [ 1194 | "winapi-i686-pc-windows-gnu", 1195 | "winapi-x86_64-pc-windows-gnu", 1196 | ] 1197 | 1198 | [[package]] 1199 | name = "winapi-i686-pc-windows-gnu" 1200 | version = "0.4.0" 1201 | source = "registry+https://github.com/rust-lang/crates.io-index" 1202 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1203 | 1204 | [[package]] 1205 | name = "winapi-x86_64-pc-windows-gnu" 1206 | version = "0.4.0" 1207 | source = "registry+https://github.com/rust-lang/crates.io-index" 1208 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1209 | -------------------------------------------------------------------------------- /bellman_vk_codegen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bellman_vk_codegen" 3 | version = "0.1.0" 4 | authors = ["Alex Vlasov "] 5 | edition = "2018" 6 | license = "MIT OR Apache-2.0" 7 | 8 | [dependencies] 9 | bellman = { package = "bellman_ce", git = "https://github.com/matter-labs/bellman", branch = "plonk_release" } 10 | handlebars = "3.*" 11 | hex = "*" 12 | serde_json = "1.*" 13 | web3 = {version = "0.8.*", default_features = false } 14 | -------------------------------------------------------------------------------- /bellman_vk_codegen/PlonkUnrolledForEthereum.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matter-labs/solidity_plonk_verifier/7bd56a690c1f06f63e5a3610b67dc098f0491c22/bellman_vk_codegen/PlonkUnrolledForEthereum.pdf -------------------------------------------------------------------------------- /bellman_vk_codegen/deposit_vk.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matter-labs/solidity_plonk_verifier/7bd56a690c1f06f63e5a3610b67dc098f0491c22/bellman_vk_codegen/deposit_vk.key -------------------------------------------------------------------------------- /bellman_vk_codegen/src/lib.rs: -------------------------------------------------------------------------------- 1 | use bellman::pairing::ff::{PrimeField, PrimeFieldRepr}; 2 | use bellman::pairing::{Engine, CurveAffine}; 3 | use bellman::plonk::better_cs::keys::{VerificationKey, Proof}; 4 | use bellman::pairing::bn256::{Bn256, Fr}; 5 | use bellman::plonk::better_cs::cs::PlonkCsWidth4WithNextStepParams; 6 | 7 | use handlebars::*; 8 | 9 | use serde_json::value::{Map}; 10 | 11 | use web3::types::U256; 12 | 13 | pub fn render_verification_key(vk: &VerificationKey, render_to_path: &str) { 14 | let mut map = Map::new(); 15 | 16 | let domain_size = vk.n.next_power_of_two().to_string(); 17 | map.insert("domain_size".to_owned(), to_json(domain_size)); 18 | 19 | let num_inputs = vk.num_inputs.to_string(); 20 | map.insert("num_inputs".to_owned(), to_json(num_inputs)); 21 | 22 | let domain = bellman::plonk::domains::Domain::::new_for_size(vk.n.next_power_of_two() as u64).unwrap(); 23 | let omega = domain.generator; 24 | map.insert("omega".to_owned(), to_json(render_scalar_to_hex(&omega))); 25 | 26 | for (i, c) in vk.selector_commitments.iter().enumerate() { 27 | let rendered = render_g1_affine_to_hex::(&c); 28 | 29 | for j in 0..2 { 30 | map.insert(format!("selector_commitment_{}_{}", i, j), to_json(&rendered[j])); 31 | } 32 | } 33 | 34 | for (i, c) in vk.next_step_selector_commitments.iter().enumerate() { 35 | let rendered = render_g1_affine_to_hex::(&c); 36 | 37 | for j in 0..2 { 38 | map.insert(format!("next_step_selector_commitment_{}_{}", i, j), to_json(&rendered[j])); 39 | } 40 | } 41 | 42 | for (i, c) in vk.permutation_commitments.iter().enumerate() { 43 | let rendered = render_g1_affine_to_hex::(&c); 44 | 45 | for j in 0..2 { 46 | map.insert(format!("permutation_commitment_{}_{}", i, j), to_json(&rendered[j])); 47 | } 48 | } 49 | 50 | for (i, c) in vk.non_residues.iter().enumerate() { 51 | let rendered = render_scalar_to_hex::(&c); 52 | 53 | map.insert(format!("permutation_non_residue_{}", i), to_json(&rendered)); 54 | } 55 | 56 | let rendered = render_g2_affine_to_hex(&vk.g2_elements[1]); 57 | 58 | map.insert("g2_x_x_c0".to_owned(), to_json(&rendered[0])); 59 | map.insert("g2_x_x_c1".to_owned(), to_json(&rendered[1])); 60 | map.insert("g2_x_y_c0".to_owned(), to_json(&rendered[2])); 61 | map.insert("g2_x_y_c1".to_owned(), to_json(&rendered[3])); 62 | 63 | let mut handlebars = Handlebars::new(); 64 | 65 | // register template from a file and assign a name to it 66 | handlebars.register_template_file("contract", "./template.sol").expect("must read the template"); 67 | 68 | // make data and render it 69 | // println!("{}", handlebars.render("contract", &map).unwrap()); 70 | 71 | let mut writer = std::io::BufWriter::with_capacity(1<<24, 72 | std::fs::File::create(render_to_path).unwrap() 73 | ); 74 | 75 | let rendered = handlebars.render("contract", &map).unwrap(); 76 | 77 | use std::io::Write; 78 | writer.write(rendered.as_bytes()).expect("must write to file"); 79 | } 80 | 81 | fn render_scalar_to_hex(el: &F) -> String { 82 | let mut buff = vec![]; 83 | let repr = el.into_repr(); 84 | repr.write_be(&mut buff).unwrap(); 85 | 86 | format!("0x{}", hex::encode(buff)) 87 | } 88 | 89 | fn render_g1_affine_to_hex(point: &E::G1Affine) -> [String; 2] { 90 | if point.is_zero() { 91 | return ["0x0".to_owned(), "0x0".to_owned()]; 92 | } 93 | 94 | let (x, y) = point.into_xy_unchecked(); 95 | [render_scalar_to_hex(&x), render_scalar_to_hex(&y)] 96 | } 97 | 98 | fn render_g2_affine_to_hex(point: &::G2Affine) -> [String; 4] { 99 | if point.is_zero() { 100 | return ["0x0".to_owned(), "0x0".to_owned(), "0x0".to_owned(), "0x0".to_owned()]; 101 | } 102 | 103 | let (x, y) = point.into_xy_unchecked(); 104 | 105 | [ 106 | render_scalar_to_hex(&x.c0), 107 | render_scalar_to_hex(&x.c1), 108 | render_scalar_to_hex(&y.c0), 109 | render_scalar_to_hex(&y.c1) 110 | ] 111 | } 112 | 113 | fn serialize_g1_for_ethereum( 114 | point: &::G1Affine 115 | ) -> (U256, U256) { 116 | if point.is_zero() { 117 | return (U256::zero(), U256::zero()); 118 | } 119 | let uncompressed = point.into_uncompressed(); 120 | 121 | let uncompressed_slice = uncompressed.as_ref(); 122 | 123 | // bellman serializes points as big endian and in the form x, y 124 | // ethereum expects the same order in memory 125 | let x = U256::from_big_endian(&uncompressed_slice[0..32]); 126 | let y = U256::from_big_endian(&uncompressed_slice[32..64]); 127 | 128 | (x, y) 129 | } 130 | 131 | fn serialize_fe_for_ethereum(field_element: &Fr) -> U256 { 132 | let mut be_bytes = [0u8; 32]; 133 | field_element 134 | .into_repr() 135 | .write_be(&mut be_bytes[..]) 136 | .expect("get new root BE bytes"); 137 | U256::from_big_endian(&be_bytes[..]) 138 | } 139 | 140 | pub fn serialize_proof(proof: &Proof) -> (Vec, Vec) { 141 | let mut inputs = vec![]; 142 | for input in proof.input_values.iter() { 143 | inputs.push(serialize_fe_for_ethereum(&input)); 144 | } 145 | let mut serialized_proof = vec![]; 146 | 147 | for c in proof.wire_commitments.iter() { 148 | let (x, y) = serialize_g1_for_ethereum(&c); 149 | serialized_proof.push(x); 150 | serialized_proof.push(y); 151 | } 152 | 153 | let (x, y) = serialize_g1_for_ethereum(&proof.grand_product_commitment); 154 | serialized_proof.push(x); 155 | serialized_proof.push(y); 156 | 157 | for c in proof.quotient_poly_commitments.iter() { 158 | let (x, y) = serialize_g1_for_ethereum(&c); 159 | serialized_proof.push(x); 160 | serialized_proof.push(y); 161 | } 162 | 163 | for c in proof.wire_values_at_z.iter() { 164 | serialized_proof.push(serialize_fe_for_ethereum(&c)); 165 | } 166 | 167 | for c in proof.wire_values_at_z_omega.iter() { 168 | serialized_proof.push(serialize_fe_for_ethereum(&c)); 169 | } 170 | 171 | serialized_proof.push(serialize_fe_for_ethereum(&proof.grand_product_at_z_omega)); 172 | serialized_proof.push(serialize_fe_for_ethereum(&proof.quotient_polynomial_at_z)); 173 | serialized_proof.push(serialize_fe_for_ethereum(&proof.linearization_polynomial_at_z)); 174 | 175 | for c in proof.permutation_polynomials_at_z.iter() { 176 | serialized_proof.push(serialize_fe_for_ethereum(&c)); 177 | } 178 | 179 | let (x, y) = serialize_g1_for_ethereum(&proof.opening_at_z_proof); 180 | serialized_proof.push(x); 181 | serialized_proof.push(y); 182 | 183 | let (x, y) = serialize_g1_for_ethereum(&proof.opening_at_z_omega_proof); 184 | serialized_proof.push(x); 185 | serialized_proof.push(y); 186 | 187 | (inputs, serialized_proof) 188 | } 189 | 190 | #[cfg(test)] 191 | mod tests { 192 | use super::*; 193 | #[test] 194 | fn render_key() { 195 | let mut reader = std::io::BufReader::with_capacity(1<<24, 196 | std::fs::File::open("./deposit_vk.key").unwrap() 197 | ); 198 | let vk = VerificationKey::::read(&mut reader).unwrap(); 199 | render_verification_key(&vk, "../Verifier.sol"); 200 | } 201 | 202 | #[test] 203 | fn render_simple_deposit_key_and_proof() { 204 | let mut reader = std::io::BufReader::with_capacity(1<<24, 205 | std::fs::File::open("./deposit_vk.key").unwrap() 206 | ); 207 | let vk = VerificationKey::::read(&mut reader).unwrap(); 208 | render_verification_key(&vk, "./test.sol"); 209 | 210 | let mut reader = std::io::BufReader::with_capacity(1<<24, 211 | std::fs::File::open("./deposit_proof.proof").unwrap() 212 | ); 213 | let proof = Proof::::read(&mut reader).unwrap(); 214 | let (inputs, proof) = serialize_proof(&proof); 215 | 216 | println!("Inputs"); 217 | let mut vec = vec![]; 218 | for i in inputs.into_iter() { 219 | vec.push(format!("\"{}\"", i)); 220 | } 221 | println!("[{}]", vec.join(",")); 222 | 223 | println!("Proof"); 224 | let mut vec = vec![]; 225 | for i in proof.into_iter() { 226 | vec.push(format!("\"{}\"", i)); 227 | } 228 | 229 | println!("[{}]", vec.join(",")); 230 | } 231 | 232 | #[test] 233 | fn render_simple_xor_key_and_proof() { 234 | let mut reader = std::io::BufReader::with_capacity(1<<24, 235 | std::fs::File::open("./xor_vk.key").unwrap() 236 | ); 237 | let vk = VerificationKey::::read(&mut reader).unwrap(); 238 | render_verification_key(&vk, "./xor.sol"); 239 | 240 | let mut reader = std::io::BufReader::with_capacity(1<<24, 241 | std::fs::File::open("./xor_proof.proof").unwrap() 242 | ); 243 | let proof = Proof::::read(&mut reader).unwrap(); 244 | let (inputs, proof) = serialize_proof(&proof); 245 | 246 | println!("Inputs"); 247 | let mut vec = vec![]; 248 | for i in inputs.into_iter() { 249 | vec.push(format!("\"{}\"", i)); 250 | } 251 | println!("[{}]", vec.join(",")); 252 | 253 | println!("Proof"); 254 | let mut vec = vec![]; 255 | for i in proof.into_iter() { 256 | vec.push(format!("\"{}\"", i)); 257 | } 258 | 259 | println!("Proof len = {}", vec.len()); 260 | 261 | println!("[{}]", vec.join(",")); 262 | } 263 | } 264 | -------------------------------------------------------------------------------- /bellman_vk_codegen/template.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.5.0 <0.7.0; 2 | 3 | library PairingsBn254 { 4 | uint256 constant q_mod = 21888242871839275222246405745257275088696311157297823662689037894645226208583; 5 | uint256 constant r_mod = 21888242871839275222246405745257275088548364400416034343698204186575808495617; 6 | uint256 constant bn254_b_coeff = 3; 7 | 8 | struct G1Point { 9 | uint256 X; 10 | uint256 Y; 11 | } 12 | 13 | struct Fr { 14 | uint256 value; 15 | } 16 | 17 | function new_fr(uint256 fr) internal pure returns (Fr memory) { 18 | require(fr < r_mod); 19 | return Fr({value: fr}); 20 | } 21 | 22 | function copy(Fr memory self) internal pure returns (Fr memory n) { 23 | n.value = self.value; 24 | } 25 | 26 | function assign(Fr memory self, Fr memory other) internal pure { 27 | self.value = other.value; 28 | } 29 | 30 | function inverse(Fr memory fr) internal view returns (Fr memory) { 31 | require(fr.value != 0); 32 | return pow(fr, r_mod-2); 33 | } 34 | 35 | function add_assign(Fr memory self, Fr memory other) internal pure { 36 | self.value = addmod(self.value, other.value, r_mod); 37 | } 38 | 39 | function sub_assign(Fr memory self, Fr memory other) internal pure { 40 | self.value = addmod(self.value, r_mod - other.value, r_mod); 41 | } 42 | 43 | function mul_assign(Fr memory self, Fr memory other) internal pure { 44 | self.value = mulmod(self.value, other.value, r_mod); 45 | } 46 | 47 | function pow(Fr memory self, uint256 power) internal view returns (Fr memory) { 48 | uint256[6] memory input = [32, 32, 32, self.value, power, r_mod]; 49 | uint256[1] memory result; 50 | bool success; 51 | assembly { 52 | success := staticcall(gas(), 0x05, input, 0xc0, result, 0x20) 53 | } 54 | require(success); 55 | return Fr({value: result[0]}); 56 | } 57 | 58 | // Encoding of field elements is: X[0] * z + X[1] 59 | struct G2Point { 60 | uint[2] X; 61 | uint[2] Y; 62 | } 63 | 64 | function P1() internal pure returns (G1Point memory) { 65 | return G1Point(1, 2); 66 | } 67 | 68 | function new_g1(uint256 x, uint256 y) internal pure returns (G1Point memory) { 69 | return G1Point(x, y); 70 | } 71 | 72 | function new_g1_checked(uint256 x, uint256 y) internal pure returns (G1Point memory) { 73 | if (x == 0 && y == 0) { 74 | // point of infinity is (0,0) 75 | return G1Point(x, y); 76 | } 77 | 78 | // check encoding 79 | require(x < q_mod); 80 | require(y < q_mod); 81 | // check on curve 82 | uint256 lhs = mulmod(y, y, q_mod); // y^2 83 | uint256 rhs = mulmod(x, x, q_mod); // x^2 84 | rhs = mulmod(rhs, x, q_mod); // x^3 85 | rhs = addmod(rhs, bn254_b_coeff, q_mod); // x^3 + b 86 | require(lhs == rhs); 87 | 88 | return G1Point(x, y); 89 | } 90 | 91 | function new_g2(uint256[2] memory x, uint256[2] memory y) internal pure returns (G2Point memory) { 92 | return G2Point(x, y); 93 | } 94 | 95 | function copy_g1(G1Point memory self) internal pure returns (G1Point memory result) { 96 | result.X = self.X; 97 | result.Y = self.Y; 98 | } 99 | 100 | function P2() internal pure returns (G2Point memory) { 101 | // for some reason ethereum expects to have c1*v + c0 form 102 | 103 | return G2Point( 104 | [0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 105 | 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed], 106 | [0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b, 107 | 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa] 108 | ); 109 | } 110 | 111 | function negate(G1Point memory self) internal pure { 112 | // The prime q in the base field F_q for G1 113 | if (self.Y == 0) { 114 | require(self.X == 0); 115 | return; 116 | } 117 | 118 | self.Y = q_mod - self.Y; 119 | } 120 | 121 | function point_add(G1Point memory p1, G1Point memory p2) 122 | internal view returns (G1Point memory r) 123 | { 124 | point_add_into_dest(p1, p2, r); 125 | return r; 126 | } 127 | 128 | function point_add_assign(G1Point memory p1, G1Point memory p2) 129 | internal view 130 | { 131 | point_add_into_dest(p1, p2, p1); 132 | } 133 | 134 | function point_add_into_dest(G1Point memory p1, G1Point memory p2, G1Point memory dest) 135 | internal view 136 | { 137 | if (p2.X == 0 && p2.Y == 0) { 138 | // we add zero, nothing happens 139 | dest.X = p1.X; 140 | dest.Y = p1.Y; 141 | return; 142 | } else if (p1.X == 0 && p1.Y == 0) { 143 | // we add into zero, and we add non-zero point 144 | dest.X = p2.X; 145 | dest.Y = p2.Y; 146 | return; 147 | } else { 148 | uint256[4] memory input; 149 | 150 | input[0] = p1.X; 151 | input[1] = p1.Y; 152 | input[2] = p2.X; 153 | input[3] = p2.Y; 154 | 155 | bool success = false; 156 | assembly { 157 | success := staticcall(gas(), 6, input, 0x80, dest, 0x40) 158 | } 159 | require(success); 160 | } 161 | } 162 | 163 | function point_sub_assign(G1Point memory p1, G1Point memory p2) 164 | internal view 165 | { 166 | point_sub_into_dest(p1, p2, p1); 167 | } 168 | 169 | function point_sub_into_dest(G1Point memory p1, G1Point memory p2, G1Point memory dest) 170 | internal view 171 | { 172 | if (p2.X == 0 && p2.Y == 0) { 173 | // we subtracted zero, nothing happens 174 | dest.X = p1.X; 175 | dest.Y = p1.Y; 176 | return; 177 | } else if (p1.X == 0 && p1.Y == 0) { 178 | // we subtract from zero, and we subtract non-zero point 179 | dest.X = p2.X; 180 | dest.Y = q_mod - p2.Y; 181 | return; 182 | } else { 183 | uint256[4] memory input; 184 | 185 | input[0] = p1.X; 186 | input[1] = p1.Y; 187 | input[2] = p2.X; 188 | input[3] = q_mod - p2.Y; 189 | 190 | bool success = false; 191 | assembly { 192 | success := staticcall(gas(), 6, input, 0x80, dest, 0x40) 193 | } 194 | require(success); 195 | } 196 | } 197 | 198 | function point_mul(G1Point memory p, Fr memory s) 199 | internal view returns (G1Point memory r) 200 | { 201 | point_mul_into_dest(p, s, r); 202 | return r; 203 | } 204 | 205 | function point_mul_assign(G1Point memory p, Fr memory s) 206 | internal view 207 | { 208 | point_mul_into_dest(p, s, p); 209 | } 210 | 211 | function point_mul_into_dest(G1Point memory p, Fr memory s, G1Point memory dest) 212 | internal view 213 | { 214 | uint[3] memory input; 215 | input[0] = p.X; 216 | input[1] = p.Y; 217 | input[2] = s.value; 218 | bool success; 219 | assembly { 220 | success := staticcall(gas(), 7, input, 0x60, dest, 0x40) 221 | } 222 | require(success); 223 | } 224 | 225 | function pairing(G1Point[] memory p1, G2Point[] memory p2) 226 | internal view returns (bool) 227 | { 228 | require(p1.length == p2.length); 229 | uint elements = p1.length; 230 | uint inputSize = elements * 6; 231 | uint[] memory input = new uint[](inputSize); 232 | for (uint i = 0; i < elements; i++) 233 | { 234 | input[i * 6 + 0] = p1[i].X; 235 | input[i * 6 + 1] = p1[i].Y; 236 | input[i * 6 + 2] = p2[i].X[0]; 237 | input[i * 6 + 3] = p2[i].X[1]; 238 | input[i * 6 + 4] = p2[i].Y[0]; 239 | input[i * 6 + 5] = p2[i].Y[1]; 240 | } 241 | uint[1] memory out; 242 | bool success; 243 | assembly { 244 | success := staticcall(gas(), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20) 245 | } 246 | require(success); 247 | return out[0] != 0; 248 | } 249 | 250 | /// Convenience method for a pairing check for two pairs. 251 | function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) 252 | internal view returns (bool) 253 | { 254 | G1Point[] memory p1 = new G1Point[](2); 255 | G2Point[] memory p2 = new G2Point[](2); 256 | p1[0] = a1; 257 | p1[1] = b1; 258 | p2[0] = a2; 259 | p2[1] = b2; 260 | return pairing(p1, p2); 261 | } 262 | } 263 | 264 | library TranscriptLibrary { 265 | // flip 0xe000000000000000000000000000000000000000000000000000000000000000; 266 | uint256 constant FR_MASK = 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; 267 | 268 | uint32 constant DST_0 = 0; 269 | uint32 constant DST_1 = 1; 270 | uint32 constant DST_CHALLENGE = 2; 271 | 272 | struct Transcript { 273 | bytes32 state_0; 274 | bytes32 state_1; 275 | uint32 challenge_counter; 276 | } 277 | 278 | function new_transcript() internal pure returns (Transcript memory t) { 279 | t.state_0 = bytes32(0); 280 | t.state_1 = bytes32(0); 281 | t.challenge_counter = 0; 282 | } 283 | 284 | function update_with_u256(Transcript memory self, uint256 value) internal pure { 285 | bytes32 old_state_0 = self.state_0; 286 | self.state_0 = keccak256(abi.encodePacked(DST_0, old_state_0, self.state_1, value)); 287 | self.state_1 = keccak256(abi.encodePacked(DST_1, old_state_0, self.state_1, value)); 288 | } 289 | 290 | function update_with_fr(Transcript memory self, PairingsBn254.Fr memory value) internal pure { 291 | update_with_u256(self, value.value); 292 | } 293 | 294 | function update_with_g1(Transcript memory self, PairingsBn254.G1Point memory p) internal pure { 295 | update_with_u256(self, p.X); 296 | update_with_u256(self, p.Y); 297 | } 298 | 299 | function get_challenge(Transcript memory self) internal pure returns(PairingsBn254.Fr memory challenge) { 300 | bytes32 query = keccak256(abi.encodePacked(DST_CHALLENGE, self.state_0, self.state_1, self.challenge_counter)); 301 | self.challenge_counter += 1; 302 | challenge = PairingsBn254.Fr({value: uint256(query) & FR_MASK}); 303 | } 304 | } 305 | 306 | contract Plonk4VerifierWithAccessToDNext { 307 | using PairingsBn254 for PairingsBn254.G1Point; 308 | using PairingsBn254 for PairingsBn254.G2Point; 309 | using PairingsBn254 for PairingsBn254.Fr; 310 | 311 | using TranscriptLibrary for TranscriptLibrary.Transcript; 312 | 313 | uint256 constant STATE_WIDTH = 4; 314 | uint256 constant ACCESSIBLE_STATE_POLYS_ON_NEXT_STEP = 1; 315 | 316 | struct VerificationKey { 317 | uint256 domain_size; 318 | uint256 num_inputs; 319 | PairingsBn254.Fr omega; 320 | PairingsBn254.G1Point[STATE_WIDTH+2] selector_commitments; // STATE_WIDTH for witness + multiplication + constant 321 | PairingsBn254.G1Point[ACCESSIBLE_STATE_POLYS_ON_NEXT_STEP] next_step_selector_commitments; 322 | PairingsBn254.G1Point[STATE_WIDTH] permutation_commitments; 323 | PairingsBn254.Fr[STATE_WIDTH-1] permutation_non_residues; 324 | PairingsBn254.G2Point g2_x; 325 | } 326 | 327 | struct Proof { 328 | uint256[] input_values; 329 | PairingsBn254.G1Point[STATE_WIDTH] wire_commitments; 330 | PairingsBn254.G1Point grand_product_commitment; 331 | PairingsBn254.G1Point[STATE_WIDTH] quotient_poly_commitments; 332 | PairingsBn254.Fr[STATE_WIDTH] wire_values_at_z; 333 | PairingsBn254.Fr[ACCESSIBLE_STATE_POLYS_ON_NEXT_STEP] wire_values_at_z_omega; 334 | PairingsBn254.Fr grand_product_at_z_omega; 335 | PairingsBn254.Fr quotient_polynomial_at_z; 336 | PairingsBn254.Fr linearization_polynomial_at_z; 337 | PairingsBn254.Fr[STATE_WIDTH-1] permutation_polynomials_at_z; 338 | 339 | PairingsBn254.G1Point opening_at_z_proof; 340 | PairingsBn254.G1Point opening_at_z_omega_proof; 341 | } 342 | 343 | struct PartialVerifierState { 344 | PairingsBn254.Fr alpha; 345 | PairingsBn254.Fr beta; 346 | PairingsBn254.Fr gamma; 347 | PairingsBn254.Fr v; 348 | PairingsBn254.Fr u; 349 | PairingsBn254.Fr z; 350 | PairingsBn254.Fr[] cached_lagrange_evals; 351 | } 352 | 353 | function evaluate_lagrange_poly_out_of_domain( 354 | uint256 poly_num, 355 | uint256 domain_size, 356 | PairingsBn254.Fr memory omega, 357 | PairingsBn254.Fr memory at 358 | ) internal view returns (PairingsBn254.Fr memory res) { 359 | require(poly_num < domain_size); 360 | PairingsBn254.Fr memory one = PairingsBn254.new_fr(1); 361 | PairingsBn254.Fr memory omega_power = omega.pow(poly_num); 362 | res = at.pow(domain_size); 363 | res.sub_assign(one); 364 | require(res.value != 0); // Vanishing polynomial can not be zero at point `at` 365 | res.mul_assign(omega_power); 366 | 367 | PairingsBn254.Fr memory den = PairingsBn254.copy(at); 368 | den.sub_assign(omega_power); 369 | den.mul_assign(PairingsBn254.new_fr(domain_size)); 370 | 371 | den = den.inverse(); 372 | 373 | res.mul_assign(den); 374 | } 375 | 376 | function batch_evaluate_lagrange_poly_out_of_domain( 377 | uint256[] memory poly_nums, 378 | uint256 domain_size, 379 | PairingsBn254.Fr memory omega, 380 | PairingsBn254.Fr memory at 381 | ) internal view returns (PairingsBn254.Fr[] memory res) { 382 | PairingsBn254.Fr memory one = PairingsBn254.new_fr(1); 383 | PairingsBn254.Fr memory tmp_1 = PairingsBn254.new_fr(0); 384 | PairingsBn254.Fr memory tmp_2 = PairingsBn254.new_fr(domain_size); 385 | PairingsBn254.Fr memory vanishing_at_z = at.pow(domain_size); 386 | vanishing_at_z.sub_assign(one); 387 | // we can not have random point z be in domain 388 | require(vanishing_at_z.value != 0); 389 | PairingsBn254.Fr[] memory nums = new PairingsBn254.Fr[](poly_nums.length); 390 | PairingsBn254.Fr[] memory dens = new PairingsBn254.Fr[](poly_nums.length); 391 | // numerators in a form omega^i * (z^n - 1) 392 | // denoms in a form (z - omega^i) * N 393 | for (uint i = 0; i < poly_nums.length; i++) { 394 | tmp_1 = omega.pow(poly_nums[i]); // power of omega 395 | nums[i].assign(vanishing_at_z); 396 | nums[i].mul_assign(tmp_1); 397 | 398 | dens[i].assign(at); // (X - omega^i) * N 399 | dens[i].sub_assign(tmp_1); 400 | dens[i].mul_assign(tmp_2); // mul by domain size 401 | } 402 | 403 | PairingsBn254.Fr[] memory partial_products = new PairingsBn254.Fr[](poly_nums.length); 404 | partial_products[0].assign(PairingsBn254.new_fr(1)); 405 | for (uint i = 1; i < dens.length; i++) { 406 | partial_products[i].assign(dens[i-1]); 407 | partial_products[i].mul_assign(partial_products[i-1]); 408 | } 409 | 410 | tmp_2.assign(partial_products[partial_products.length - 1]); 411 | tmp_2.mul_assign(dens[dens.length - 1]); 412 | tmp_2 = tmp_2.inverse(); // tmp_2 contains a^-1 * b^-1 (with! the last one) 413 | 414 | for (uint i = dens.length - 1; i < dens.length; i--) { 415 | tmp_1.assign(tmp_2); // all inversed 416 | tmp_1.mul_assign(partial_products[i]); // clear lowest terms 417 | tmp_2.mul_assign(dens[i]); 418 | dens[i].assign(tmp_1); 419 | } 420 | 421 | for (uint i = 0; i < nums.length; i++) { 422 | nums[i].mul_assign(dens[i]); 423 | } 424 | 425 | return nums; 426 | } 427 | 428 | function evaluate_vanishing( 429 | uint256 domain_size, 430 | PairingsBn254.Fr memory at 431 | ) internal view returns (PairingsBn254.Fr memory res) { 432 | res = at.pow(domain_size); 433 | res.sub_assign(PairingsBn254.new_fr(1)); 434 | } 435 | 436 | function verify_at_z( 437 | PartialVerifierState memory state, 438 | Proof memory proof, 439 | VerificationKey memory vk 440 | ) internal view returns (bool) { 441 | PairingsBn254.Fr memory lhs = evaluate_vanishing(vk.domain_size, state.z); 442 | require(lhs.value != 0); // we can not check a polynomial relationship if point `z` is in the domain 443 | lhs.mul_assign(proof.quotient_polynomial_at_z); 444 | 445 | PairingsBn254.Fr memory quotient_challenge = PairingsBn254.new_fr(1); 446 | PairingsBn254.Fr memory rhs = PairingsBn254.copy(proof.linearization_polynomial_at_z); 447 | 448 | // public inputs 449 | PairingsBn254.Fr memory tmp = PairingsBn254.new_fr(0); 450 | for (uint256 i = 0; i < proof.input_values.length; i++) { 451 | tmp.assign(state.cached_lagrange_evals[i]); 452 | tmp.mul_assign(PairingsBn254.new_fr(proof.input_values[i])); 453 | rhs.add_assign(tmp); 454 | } 455 | 456 | quotient_challenge.mul_assign(state.alpha); 457 | 458 | PairingsBn254.Fr memory z_part = PairingsBn254.copy(proof.grand_product_at_z_omega); 459 | for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) { 460 | tmp.assign(proof.permutation_polynomials_at_z[i]); 461 | tmp.mul_assign(state.beta); 462 | tmp.add_assign(state.gamma); 463 | tmp.add_assign(proof.wire_values_at_z[i]); 464 | 465 | z_part.mul_assign(tmp); 466 | } 467 | 468 | tmp.assign(state.gamma); 469 | // we need a wire value of the last polynomial in enumeration 470 | tmp.add_assign(proof.wire_values_at_z[STATE_WIDTH - 1]); 471 | 472 | z_part.mul_assign(tmp); 473 | z_part.mul_assign(quotient_challenge); 474 | 475 | rhs.sub_assign(z_part); 476 | 477 | quotient_challenge.mul_assign(state.alpha); 478 | 479 | tmp.assign(state.cached_lagrange_evals[0]); 480 | tmp.mul_assign(quotient_challenge); 481 | 482 | rhs.sub_assign(tmp); 483 | 484 | return lhs.value == rhs.value; 485 | } 486 | 487 | function reconstruct_d( 488 | PartialVerifierState memory state, 489 | Proof memory proof, 490 | VerificationKey memory vk 491 | ) internal view returns (PairingsBn254.G1Point memory res) { 492 | // we compute what power of v is used as a delinearization factor in batch opening of 493 | // commitments. Let's label W(x) = 1 / (x - z) * 494 | // [ 495 | // t_0(x) + z^n * t_1(x) + z^2n * t_2(x) + z^3n * t_3(x) - t(z) 496 | // + v (r(x) - r(z)) 497 | // + v^{2..5} * (witness(x) - witness(z)) 498 | // + v^(6..8) * (permutation(x) - permutation(z)) 499 | // ] 500 | // W'(x) = 1 / (x - z*omega) * 501 | // [ 502 | // + v^9 (z(x) - z(z*omega)) <- we need this power 503 | // + v^10 * (d(x) - d(z*omega)) 504 | // ] 505 | // 506 | // we pay a little for a few arithmetic operations to not introduce another constant 507 | uint256 power_for_z_omega_opening = 1 + 1 + STATE_WIDTH + STATE_WIDTH - 1; 508 | res = PairingsBn254.copy_g1(vk.selector_commitments[STATE_WIDTH + 1]); 509 | 510 | PairingsBn254.G1Point memory tmp_g1 = PairingsBn254.P1(); 511 | PairingsBn254.Fr memory tmp_fr = PairingsBn254.new_fr(0); 512 | 513 | // addition gates 514 | for (uint256 i = 0; i < STATE_WIDTH; i++) { 515 | tmp_g1 = vk.selector_commitments[i].point_mul(proof.wire_values_at_z[i]); 516 | res.point_add_assign(tmp_g1); 517 | } 518 | 519 | // multiplication gate 520 | tmp_fr.assign(proof.wire_values_at_z[0]); 521 | tmp_fr.mul_assign(proof.wire_values_at_z[1]); 522 | tmp_g1 = vk.selector_commitments[STATE_WIDTH].point_mul(tmp_fr); 523 | res.point_add_assign(tmp_g1); 524 | 525 | // d_next 526 | tmp_g1 = vk.next_step_selector_commitments[0].point_mul(proof.wire_values_at_z_omega[0]); 527 | res.point_add_assign(tmp_g1); 528 | 529 | // z * non_res * beta + gamma + a 530 | PairingsBn254.Fr memory grand_product_part_at_z = PairingsBn254.copy(state.z); 531 | grand_product_part_at_z.mul_assign(state.beta); 532 | grand_product_part_at_z.add_assign(proof.wire_values_at_z[0]); 533 | grand_product_part_at_z.add_assign(state.gamma); 534 | for (uint256 i = 0; i < vk.permutation_non_residues.length; i++) { 535 | tmp_fr.assign(state.z); 536 | tmp_fr.mul_assign(vk.permutation_non_residues[i]); 537 | tmp_fr.mul_assign(state.beta); 538 | tmp_fr.add_assign(state.gamma); 539 | tmp_fr.add_assign(proof.wire_values_at_z[i+1]); 540 | 541 | grand_product_part_at_z.mul_assign(tmp_fr); 542 | } 543 | 544 | grand_product_part_at_z.mul_assign(state.alpha); 545 | 546 | tmp_fr.assign(state.cached_lagrange_evals[0]); 547 | tmp_fr.mul_assign(state.alpha); 548 | tmp_fr.mul_assign(state.alpha); 549 | 550 | grand_product_part_at_z.add_assign(tmp_fr); 551 | 552 | PairingsBn254.Fr memory grand_product_part_at_z_omega = state.v.pow(power_for_z_omega_opening); 553 | grand_product_part_at_z_omega.mul_assign(state.u); 554 | 555 | PairingsBn254.Fr memory last_permutation_part_at_z = PairingsBn254.new_fr(1); 556 | for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) { 557 | tmp_fr.assign(state.beta); 558 | tmp_fr.mul_assign(proof.permutation_polynomials_at_z[i]); 559 | tmp_fr.add_assign(state.gamma); 560 | tmp_fr.add_assign(proof.wire_values_at_z[i]); 561 | 562 | last_permutation_part_at_z.mul_assign(tmp_fr); 563 | } 564 | 565 | last_permutation_part_at_z.mul_assign(state.beta); 566 | last_permutation_part_at_z.mul_assign(proof.grand_product_at_z_omega); 567 | last_permutation_part_at_z.mul_assign(state.alpha); 568 | 569 | // add to the linearization 570 | tmp_g1 = proof.grand_product_commitment.point_mul(grand_product_part_at_z); 571 | tmp_g1.point_sub_assign(vk.permutation_commitments[STATE_WIDTH - 1].point_mul(last_permutation_part_at_z)); 572 | 573 | res.point_add_assign(tmp_g1); 574 | res.point_mul_assign(state.v); 575 | 576 | res.point_add_assign(proof.grand_product_commitment.point_mul(grand_product_part_at_z_omega)); 577 | } 578 | 579 | function verify_commitments( 580 | PartialVerifierState memory state, 581 | Proof memory proof, 582 | VerificationKey memory vk 583 | ) internal view returns (bool) { 584 | PairingsBn254.G1Point memory d = reconstruct_d(state, proof, vk); 585 | 586 | PairingsBn254.Fr memory z_in_domain_size = state.z.pow(vk.domain_size); 587 | 588 | PairingsBn254.G1Point memory tmp_g1 = PairingsBn254.P1(); 589 | 590 | PairingsBn254.Fr memory aggregation_challenge = PairingsBn254.new_fr(1); 591 | 592 | PairingsBn254.G1Point memory commitment_aggregation = PairingsBn254.copy_g1(proof.quotient_poly_commitments[0]); 593 | PairingsBn254.Fr memory tmp_fr = PairingsBn254.new_fr(1); 594 | for (uint i = 1; i < proof.quotient_poly_commitments.length; i++) { 595 | tmp_fr.mul_assign(z_in_domain_size); 596 | tmp_g1 = proof.quotient_poly_commitments[i].point_mul(tmp_fr); 597 | commitment_aggregation.point_add_assign(tmp_g1); 598 | } 599 | 600 | aggregation_challenge.mul_assign(state.v); 601 | commitment_aggregation.point_add_assign(d); 602 | 603 | for (uint i = 0; i < proof.wire_commitments.length; i++) { 604 | aggregation_challenge.mul_assign(state.v); 605 | tmp_g1 = proof.wire_commitments[i].point_mul(aggregation_challenge); 606 | commitment_aggregation.point_add_assign(tmp_g1); 607 | } 608 | 609 | for (uint i = 0; i < vk.permutation_commitments.length - 1; i++) { 610 | aggregation_challenge.mul_assign(state.v); 611 | tmp_g1 = vk.permutation_commitments[i].point_mul(aggregation_challenge); 612 | commitment_aggregation.point_add_assign(tmp_g1); 613 | } 614 | 615 | aggregation_challenge.mul_assign(state.v); 616 | 617 | aggregation_challenge.mul_assign(state.v); 618 | 619 | tmp_fr.assign(aggregation_challenge); 620 | tmp_fr.mul_assign(state.u); 621 | tmp_g1 = proof.wire_commitments[STATE_WIDTH - 1].point_mul(tmp_fr); 622 | commitment_aggregation.point_add_assign(tmp_g1); 623 | 624 | // collect opening values 625 | aggregation_challenge = PairingsBn254.new_fr(1); 626 | 627 | PairingsBn254.Fr memory aggregated_value = PairingsBn254.copy(proof.quotient_polynomial_at_z); 628 | 629 | aggregation_challenge.mul_assign(state.v); 630 | 631 | tmp_fr.assign(proof.linearization_polynomial_at_z); 632 | tmp_fr.mul_assign(aggregation_challenge); 633 | aggregated_value.add_assign(tmp_fr); 634 | 635 | for (uint i = 0; i < proof.wire_values_at_z.length; i++) { 636 | aggregation_challenge.mul_assign(state.v); 637 | 638 | tmp_fr.assign(proof.wire_values_at_z[i]); 639 | tmp_fr.mul_assign(aggregation_challenge); 640 | aggregated_value.add_assign(tmp_fr); 641 | } 642 | 643 | for (uint i = 0; i < proof.permutation_polynomials_at_z.length; i++) { 644 | aggregation_challenge.mul_assign(state.v); 645 | 646 | tmp_fr.assign(proof.permutation_polynomials_at_z[i]); 647 | tmp_fr.mul_assign(aggregation_challenge); 648 | aggregated_value.add_assign(tmp_fr); 649 | } 650 | 651 | aggregation_challenge.mul_assign(state.v); 652 | 653 | tmp_fr.assign(proof.grand_product_at_z_omega); 654 | tmp_fr.mul_assign(aggregation_challenge); 655 | tmp_fr.mul_assign(state.u); 656 | aggregated_value.add_assign(tmp_fr); 657 | 658 | aggregation_challenge.mul_assign(state.v); 659 | 660 | tmp_fr.assign(proof.wire_values_at_z_omega[0]); 661 | tmp_fr.mul_assign(aggregation_challenge); 662 | tmp_fr.mul_assign(state.u); 663 | aggregated_value.add_assign(tmp_fr); 664 | 665 | commitment_aggregation.point_sub_assign(PairingsBn254.P1().point_mul(aggregated_value)); 666 | 667 | PairingsBn254.G1Point memory pair_with_generator = commitment_aggregation; 668 | pair_with_generator.point_add_assign(proof.opening_at_z_proof.point_mul(state.z)); 669 | 670 | tmp_fr.assign(state.z); 671 | tmp_fr.mul_assign(vk.omega); 672 | tmp_fr.mul_assign(state.u); 673 | pair_with_generator.point_add_assign(proof.opening_at_z_omega_proof.point_mul(tmp_fr)); 674 | 675 | PairingsBn254.G1Point memory pair_with_x = proof.opening_at_z_omega_proof.point_mul(state.u); 676 | pair_with_x.point_add_assign(proof.opening_at_z_proof); 677 | pair_with_x.negate(); 678 | 679 | return PairingsBn254.pairingProd2(pair_with_generator, PairingsBn254.P2(), pair_with_x, vk.g2_x); 680 | } 681 | 682 | function verify_initial( 683 | PartialVerifierState memory state, 684 | Proof memory proof, 685 | VerificationKey memory vk 686 | ) internal view returns (bool) { 687 | require(proof.input_values.length == vk.num_inputs); 688 | require(vk.num_inputs >= 1); 689 | TranscriptLibrary.Transcript memory transcript = TranscriptLibrary.new_transcript(); 690 | for (uint256 i = 0; i < vk.num_inputs; i++) { 691 | transcript.update_with_u256(proof.input_values[i]); 692 | } 693 | 694 | for (uint256 i = 0; i < proof.wire_commitments.length; i++) { 695 | transcript.update_with_g1(proof.wire_commitments[i]); 696 | } 697 | 698 | state.beta = transcript.get_challenge(); 699 | state.gamma = transcript.get_challenge(); 700 | 701 | transcript.update_with_g1(proof.grand_product_commitment); 702 | state.alpha = transcript.get_challenge(); 703 | 704 | for (uint256 i = 0; i < proof.quotient_poly_commitments.length; i++) { 705 | transcript.update_with_g1(proof.quotient_poly_commitments[i]); 706 | } 707 | 708 | state.z = transcript.get_challenge(); 709 | 710 | uint256[] memory lagrange_poly_numbers = new uint256[](vk.num_inputs); 711 | for (uint256 i = 0; i < lagrange_poly_numbers.length; i++) { 712 | lagrange_poly_numbers[i] = i; 713 | } 714 | 715 | state.cached_lagrange_evals = batch_evaluate_lagrange_poly_out_of_domain( 716 | lagrange_poly_numbers, 717 | vk.domain_size, 718 | vk.omega, state.z 719 | ); 720 | 721 | bool valid = verify_at_z(state, proof, vk); 722 | 723 | if (valid == false) { 724 | return false; 725 | } 726 | 727 | for (uint256 i = 0; i < proof.wire_values_at_z.length; i++) { 728 | transcript.update_with_fr(proof.wire_values_at_z[i]); 729 | } 730 | 731 | for (uint256 i = 0; i < proof.wire_values_at_z_omega.length; i++) { 732 | transcript.update_with_fr(proof.wire_values_at_z_omega[i]); 733 | } 734 | 735 | for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) { 736 | transcript.update_with_fr(proof.permutation_polynomials_at_z[i]); 737 | } 738 | 739 | transcript.update_with_fr(proof.quotient_polynomial_at_z); 740 | transcript.update_with_fr(proof.linearization_polynomial_at_z); 741 | 742 | state.v = transcript.get_challenge(); 743 | transcript.update_with_g1(proof.opening_at_z_proof); 744 | transcript.update_with_g1(proof.opening_at_z_omega_proof); 745 | state.u = transcript.get_challenge(); 746 | 747 | return true; 748 | } 749 | 750 | // This verifier is for a PLONK with a state width 4 751 | // and main gate equation 752 | // q_a(X) * a(X) + 753 | // q_b(X) * b(X) + 754 | // q_c(X) * c(X) + 755 | // q_d(X) * d(X) + 756 | // q_m(X) * a(X) * b(X) + 757 | // q_constants(X)+ 758 | // q_d_next(X) * d(X*omega) 759 | // where q_{}(X) are selectors a, b, c, d - state (witness) polynomials 760 | // q_d_next(X) "peeks" into the next row of the trace, so it takes 761 | // the same d(X) polynomial, but shifted 762 | 763 | function verify(Proof memory proof, VerificationKey memory vk) internal view returns (bool) { 764 | PartialVerifierState memory state; 765 | 766 | bool valid = verify_initial(state, proof, vk); 767 | 768 | if (valid == false) { 769 | return false; 770 | } 771 | 772 | valid = verify_commitments(state, proof, vk); 773 | 774 | return valid; 775 | } 776 | } 777 | 778 | contract KeyedVerifier is Plonk4VerifierWithAccessToDNext { 779 | uint256 constant SERIALIZED_PROOF_LENGTH = 33; 780 | 781 | function get_verification_key() internal pure returns(VerificationKey memory vk) { 782 | vk.domain_size = {{domain_size}}; 783 | vk.num_inputs = {{num_inputs}}; 784 | vk.omega = PairingsBn254.new_fr({{omega}}); 785 | vk.selector_commitments[0] = PairingsBn254.new_g1( 786 | {{selector_commitment_0_0}}, 787 | {{selector_commitment_0_1}} 788 | ); 789 | vk.selector_commitments[1] = PairingsBn254.new_g1( 790 | {{selector_commitment_1_0}}, 791 | {{selector_commitment_1_1}} 792 | ); 793 | vk.selector_commitments[2] = PairingsBn254.new_g1( 794 | {{selector_commitment_2_0}}, 795 | {{selector_commitment_2_1}} 796 | ); 797 | vk.selector_commitments[3] = PairingsBn254.new_g1( 798 | {{selector_commitment_3_0}}, 799 | {{selector_commitment_3_1}} 800 | ); 801 | vk.selector_commitments[4] = PairingsBn254.new_g1( 802 | {{selector_commitment_4_0}}, 803 | {{selector_commitment_4_1}} 804 | ); 805 | vk.selector_commitments[5] = PairingsBn254.new_g1( 806 | {{selector_commitment_5_0}}, 807 | {{selector_commitment_5_1}} 808 | ); 809 | 810 | // we only have access to value of the d(x) witness polynomial on the next 811 | // trace step, so we only need one element here and deal with it in other places 812 | // by having this in mind 813 | vk.next_step_selector_commitments[0] = PairingsBn254.new_g1( 814 | {{next_step_selector_commitment_0_0}}, 815 | {{next_step_selector_commitment_0_1}} 816 | ); 817 | 818 | vk.permutation_commitments[0] = PairingsBn254.new_g1( 819 | {{permutation_commitment_0_0}}, 820 | {{permutation_commitment_0_1}} 821 | ); 822 | vk.permutation_commitments[1] = PairingsBn254.new_g1( 823 | {{permutation_commitment_1_0}}, 824 | {{permutation_commitment_1_1}} 825 | ); 826 | vk.permutation_commitments[2] = PairingsBn254.new_g1( 827 | {{permutation_commitment_2_0}}, 828 | {{permutation_commitment_2_1}} 829 | ); 830 | vk.permutation_commitments[3] = PairingsBn254.new_g1( 831 | {{permutation_commitment_3_0}}, 832 | {{permutation_commitment_3_1}} 833 | ); 834 | 835 | vk.permutation_non_residues[0] = PairingsBn254.new_fr( 836 | {{permutation_non_residue_0}} 837 | ); 838 | vk.permutation_non_residues[1] = PairingsBn254.new_fr( 839 | {{permutation_non_residue_1}} 840 | ); 841 | vk.permutation_non_residues[2] = PairingsBn254.new_fr( 842 | {{permutation_non_residue_2}} 843 | ); 844 | 845 | vk.g2_x = PairingsBn254.new_g2( 846 | [{{g2_x_x_c1}}, 847 | {{g2_x_x_c0}}], 848 | [{{g2_x_y_c1}}, 849 | {{g2_x_y_c0}}] 850 | ); 851 | } 852 | 853 | 854 | function deserialize_proof( 855 | uint256[] memory public_inputs, 856 | uint256[] memory serialized_proof 857 | ) internal pure returns(Proof memory proof) { 858 | require(serialized_proof.length == SERIALIZED_PROOF_LENGTH); 859 | proof.input_values = new uint256[](public_inputs.length); 860 | for (uint256 i = 0; i < public_inputs.length; i++) { 861 | proof.input_values[i] = public_inputs[i]; 862 | } 863 | 864 | uint256 j = 0; 865 | for (uint256 i = 0; i < STATE_WIDTH; i++) { 866 | proof.wire_commitments[i] = PairingsBn254.new_g1_checked( 867 | serialized_proof[j], 868 | serialized_proof[j+1] 869 | ); 870 | 871 | j += 2; 872 | } 873 | 874 | proof.grand_product_commitment = PairingsBn254.new_g1_checked( 875 | serialized_proof[j], 876 | serialized_proof[j+1] 877 | ); 878 | j += 2; 879 | 880 | for (uint256 i = 0; i < STATE_WIDTH; i++) { 881 | proof.quotient_poly_commitments[i] = PairingsBn254.new_g1_checked( 882 | serialized_proof[j], 883 | serialized_proof[j+1] 884 | ); 885 | 886 | j += 2; 887 | } 888 | 889 | for (uint256 i = 0; i < STATE_WIDTH; i++) { 890 | proof.wire_values_at_z[i] = PairingsBn254.new_fr( 891 | serialized_proof[j] 892 | ); 893 | 894 | j += 1; 895 | } 896 | 897 | for (uint256 i = 0; i < proof.wire_values_at_z_omega.length; i++) { 898 | proof.wire_values_at_z_omega[i] = PairingsBn254.new_fr( 899 | serialized_proof[j] 900 | ); 901 | 902 | j += 1; 903 | } 904 | 905 | proof.grand_product_at_z_omega = PairingsBn254.new_fr( 906 | serialized_proof[j] 907 | ); 908 | 909 | j += 1; 910 | 911 | proof.quotient_polynomial_at_z = PairingsBn254.new_fr( 912 | serialized_proof[j] 913 | ); 914 | 915 | j += 1; 916 | 917 | proof.linearization_polynomial_at_z = PairingsBn254.new_fr( 918 | serialized_proof[j] 919 | ); 920 | 921 | j += 1; 922 | 923 | for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) { 924 | proof.permutation_polynomials_at_z[i] = PairingsBn254.new_fr( 925 | serialized_proof[j] 926 | ); 927 | 928 | j += 1; 929 | } 930 | 931 | proof.opening_at_z_proof = PairingsBn254.new_g1_checked( 932 | serialized_proof[j], 933 | serialized_proof[j+1] 934 | ); 935 | j += 2; 936 | 937 | proof.opening_at_z_omega_proof = PairingsBn254.new_g1_checked( 938 | serialized_proof[j], 939 | serialized_proof[j+1] 940 | ); 941 | } 942 | 943 | function verify_serialized_proof( 944 | uint256[] memory public_inputs, 945 | uint256[] memory serialized_proof 946 | ) public view returns (bool) { 947 | VerificationKey memory vk = get_verification_key(); 948 | require(vk.num_inputs == public_inputs.length); 949 | 950 | Proof memory proof = deserialize_proof(public_inputs, serialized_proof); 951 | 952 | bool valid = verify(proof, vk); 953 | 954 | return valid; 955 | } 956 | } 957 | -------------------------------------------------------------------------------- /deny.toml: -------------------------------------------------------------------------------- 1 | all-features = false 2 | no-default-features = false 3 | 4 | [advisories] 5 | vulnerability = "deny" 6 | unmaintained = "warn" 7 | yanked = "warn" 8 | notice = "warn" 9 | ignore = [ 10 | #"RUSTSEC-0000-0000", 11 | ] 12 | 13 | [licenses] 14 | unlicensed = "deny" 15 | allow = [ 16 | #"Apache-2.0 WITH LLVM-exception", 17 | "MIT", 18 | "Apache-2.0", 19 | "ISC", 20 | "Unlicense", 21 | "MPL-2.0", 22 | "Unicode-DFS-2016", 23 | "CC0-1.0", 24 | "BSD-2-Clause", 25 | "BSD-3-Clause", 26 | "Zlib", 27 | ] 28 | deny = [ 29 | #"Nokia", 30 | ] 31 | copyleft = "warn" 32 | allow-osi-fsf-free = "neither" 33 | default = "deny" 34 | confidence-threshold = 0.8 35 | exceptions = [ 36 | # Each entry is the crate and version constraint, and its specific allow 37 | # list 38 | #{ allow = ["Zlib"], name = "adler32", version = "*" }, 39 | ] 40 | 41 | unused-allowed-license = "allow" 42 | 43 | [licenses.private] 44 | ignore = false 45 | registries = [ 46 | #"https://sekretz.com/registry 47 | ] 48 | 49 | [bans] 50 | multiple-versions = "warn" 51 | wildcards = "allow" 52 | highlight = "all" 53 | workspace-default-features = "allow" 54 | external-default-features = "allow" 55 | allow = [ 56 | #{ name = "ansi_term", version = "=0.11.0" }, 57 | ] 58 | # List of crates to deny 59 | deny = [ 60 | # Each entry the name of a crate and a version range. If version is 61 | # not specified, all versions will be matched. 62 | #{ name = "ansi_term", version = "=0.11.0" }, 63 | ] 64 | 65 | skip = [ 66 | #{ name = "ansi_term", version = "=0.11.0" }, 67 | ] 68 | skip-tree = [ 69 | #{ name = "ansi_term", version = "=0.11.0", depth = 20 }, 70 | ] 71 | 72 | [sources] 73 | unknown-registry = "deny" 74 | unknown-git = "allow" 75 | allow-registry = ["https://github.com/rust-lang/crates.io-index"] 76 | allow-git = [] 77 | 78 | [sources.allow-org] 79 | #github = ["matter-labs"] 80 | --------------------------------------------------------------------------------