├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── task.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── build.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── go-circuit ├── poseidon.go └── semaphore.go ├── go.mod ├── go.sum ├── lean-circuit ├── LeanCircuit.lean ├── LeanCircuit │ ├── Poseidon │ │ ├── Constants.lean │ │ ├── Correctness.lean │ │ └── Spec.lean │ └── SemanticEquivalence.lean ├── Main.lean ├── lake-manifest.json ├── lakefile.lean └── lean-toolchain ├── run.ps1 └── run.sh /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # General Code 2 | * @reilabs/formal 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Found something wrong? Let us know. 4 | title: "[BUG] " 5 | labels: bug 6 | assignees: '' 7 | --- 8 | 9 | # Describe the Bug 10 | 11 | A clear and concise description of what the bug is. 12 | 13 | # To Reproduce 14 | 15 | Steps to reproduce the behavior: 16 | 17 | 1. Go to '...' 18 | 2. Click on '....' 19 | 3. Scroll down to '....' 20 | 4. See error 21 | 22 | # Expected Behaviour 23 | 24 | A clear and concise description of what you expected to happen. 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/task.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Task 3 | about: Something that needs doing. 4 | title: "[TASK] " 5 | labels: enhancement 6 | assignees: '' 7 | --- 8 | 9 | # Description 10 | 11 | What is this about? 12 | 13 | # Spec 14 | 15 | Give details. 16 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | 4 | 5 | # Details 6 | 7 | 8 | 9 | # Checklist 10 | 11 | - [ ] Code is formatted akin to the other code in the repo. 12 | - [ ] Documentation has been updated if necessary. 13 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: push 3 | 4 | jobs: 5 | build: 6 | name: Build 7 | runs-on: ubuntu-latest 8 | timeout-minutes: 600 9 | steps: 10 | - name: Checkout repo 11 | uses: actions/checkout@v3 12 | with: 13 | fetch-depth: 0 14 | - name: Install Elan 15 | run: | 16 | curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | sh -s -- -y -v --default-toolchain leanprover/lean4:nightly-2023-07-12 17 | echo "LAKE_VERSION=$(~/.elan/bin/lake --version)" >> $GITHUB_ENV 18 | - name: Cache dependencies 19 | uses: actions/cache@v3 20 | with: 21 | path: lean-circuit/lake-packages 22 | key: "${{ env.LAKE_VERSION }}" 23 | - name: Set up Go 24 | uses: actions/setup-go@v4 25 | with: 26 | go-version-file: './go.mod' 27 | - name: Go Format 28 | run: gofmt -s -w . && git diff --exit-code 29 | - name: Go Vet 30 | run: go vet ./... 31 | - name: Go Tidy 32 | run: go mod tidy && git diff --exit-code 33 | - name: Go Mod 34 | run: go mod download 35 | - name: Go Mod Verify 36 | run: go mod verify 37 | - name: Build 38 | run: go build -o gnark-lean-demo -v ./... 39 | - name: Export circuit 40 | run: ./gnark-lean-demo extract-circuit --out=lean-circuit/LeanCircuit.lean 41 | - name: Build lean project 42 | run: | 43 | cd lean-circuit 44 | ~/.elan/bin/lake exe cache get 45 | ~/.elan/bin/lake build 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lean-circuit/build 2 | lean-circuit/.cache 3 | lean-circuit/lean-packages/* 4 | lean-circuit/lake-packages/* 5 | !lean-circuit/lean-packages/manifest.json 6 | gnark-lean-demo 7 | *.exe -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | This document exists as a brief introduction for how you can contribute to this 4 | demo repository. It includes a guide to 5 | [the structure of the repository](#repository-structure), 6 | [building and testing](#building-and-testing) and 7 | [getting your code on `main`](#getting-your-code-on-main). 8 | 9 | If you are new to Go or Lean, there are also corresponding guides to 10 | getting started [with Go](#new-to-go) and [with Lean](#new-to-lean), in which we 11 | provide some good resources for getting started. 12 | 13 | ## Repository Structure 14 | 15 | The Go circuit that is being verified in this demo is defined in 16 | [`semaphore.go`](go-circuit/semaphore.go) and contains an implementation of the 17 | Semaphore protocol using the aforementioned gnark library for the Go language. 18 | This is a reimplementation of the original 19 | [circom circuit](https://github.com/semaphore-protocol/semaphore/blob/main/packages/circuits/semaphore.circom) 20 | developed for the Semaphore protocol. 21 | 22 | This implementation makes use of the 23 | [`AbsDefine`](https://github.com/reilabs/gnark-lean-extractor/blob/main/abstractor/abstractor.go#L23) 24 | function from the Gnark Extractor to mark calls to gadgets, hence helping to 25 | create readable code in the extracted Lean. 26 | 27 | The result of the automatic translation from the Go circuit to Lean can be seen 28 | in [`LeanCircuit.lean`](lean-circuit/LeanCircuit.lean). 29 | 30 | For more information on how to re-run the extraction, or verify the generated 31 | Lean, see [below](#building-and-testing). 32 | 33 | ## Building and Testing 34 | 35 | We recommend that you do not take our word for it that this works and that the 36 | proofs verify, but that you should try it yourself! 37 | 38 | The first step in doing this is to build the go project and run the extraction 39 | to Lean yourself. This can be done as follows. 40 | 41 | 1. Clone the repository into a location of your choice. 42 | 43 | ```sh 44 | git clone https://github.com/reilabs/gnark-lean-demo gnark-lean-demo 45 | ``` 46 | 47 | 2. Build the go circuit project using `go` (meaning that you will need to have 48 | that toolchain set up). 49 | 50 | ```sh 51 | cd gnark-lean-demo/go-circuit 52 | go build 53 | ``` 54 | 55 | 3. Extract the circuit into place in the Lean project. 56 | 57 | ```sh 58 | ./go-circuit extract-circuit --out ../lean-circuit/LeanCircuit.lean 59 | ``` 60 | 61 | Running this extraction on the Go implementation of the circuit produces an 62 | equivalent implementation of this circuit in Lean. You can verify that 63 | implementation and the accompanying proofs as follows: 64 | 65 | 1. Change directory to the lean project. 66 | 67 | ```sh 68 | cd ../lean-circuit 69 | ``` 70 | 71 | 2. Build the lean project, thereby verifying it. This relies on having the 72 | `lake` build tool for Lean on your path. 73 | 74 | ```sh 75 | lake build 76 | ``` 77 | 78 | ## Getting Your Code on `main` 79 | 80 | This repository works on a fork and 81 | [pull request](https://github.com/reilabs/gnark-lean-demo/pulls) workflow, with 82 | code review and CI as an integral part of the process. This works as follows: 83 | 84 | 1. If necessary, you fork the repository, but if you have access to do so please 85 | create a branch. 86 | 2. You make your changes on that branch. 87 | 3. Pull request that branch against main. 88 | 4. The pull request will be reviewed and CI will be run on it. 89 | 5. Once the reviewer(s) have accepted the code and CI has passed, the code will 90 | be merged to `main`. 91 | 92 | ## New to Go? 93 | 94 | If you are new to working with [Go](https://go.dev), a great place to start is 95 | the official set of [tutorials](https://go.dev/learn/). They explain how to 96 | [install](https://go.dev/doc/install) and set the language up, as well as an 97 | [interactive tour](https://go.dev/tour/welcome/1) of how to use the language. 98 | 99 | We recommend being familiar with the language and the `go` command-line 100 | interface to the build system and compiler before interacting with the Go 101 | portion of this repository. 102 | 103 | ## New to Lean? 104 | 105 | If you are new to working with [Lean](https://leanprover.github.io), the best 106 | starting point is the [Lean 4 Manual](https://leanprover.github.io/lean4/doc/). 107 | 108 | While that guide contains sections on using Lean for both theorem proving and as 109 | a programming language, we recommend following the 110 | [theorem proving in Lean 4](https://leanprover.github.io/theorem_proving_in_lean4/) 111 | tutorial. We also recommend looking at 112 | [mathematics in lean](https://leanprover-community.github.io/mathematics_in_lean/index.html), 113 | and the documentation for [mathlib 4](https://leanprover-community.github.io/mathlib4_docs/) 114 | as the concepts there are used in the dependencies of this demo. 115 | 116 | Note that many of the resources on lean are for the old Lean 3 version. This 117 | project, and Reilabs in general, make use of the new Lean 4 implementation for 118 | its many 119 | [enhancements](https://leanprover.github.io/lean4/doc/lean3changes.html). There 120 | is no compatibility between the two versions, so please check that any resources 121 | you find are for the correct version. 122 | 123 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2023 Reilabs Sp. z o.o. 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | # Formal Verification of Gnark Circuits 10 | 11 | This repository contains an example of using Reilabs' 12 | [gnark-lean-extractor](https://github.com/reilabs/gnark-lean-extractor) library 13 | to prove the correctness of a [gnark](https://github.com/ConsenSys/gnark) 14 | reimplementation of the circuits necessary to implement and operate the 15 | [Semaphore](https://semaphore.appliedzkp.org) protocol. 16 | 17 | Under the hood, this repository makes heavy use of Reilabs' 18 | [proven-zk](https://github.com/reilabs/proven-zk) library. It is a 19 | [lean](https://leanprover.github.io) library to aid in the formal verification 20 | of circuits produced by the extractor. 21 | 22 | For guidelines on how to build these things for yourself, or to contribute to 23 | the repository, see our [contributing guide](./CONTRIBUTING.md). It also 24 | contains a guide to the structure of the repository. 25 | 26 | ## Verified Properties 27 | 28 | The [main lean file](lean-circuit/Main.lean) contains formulations and 29 | accompanying proofs of the following properties for the circuit. 30 | 31 | 1. **Poseidon Equivalence:** The equivalence of the 32 | [Poseidon hash implementation](./go-circuit/poseidon.go) to an 33 | [implementation](./lean-circuit/LeanCircuit/Poseidon/Spec.lean) very closely 34 | based on the Poseidon 35 | [reference implementation](https://extgit.iaik.tugraz.at/krypto/hadeshash). 36 | 2. **No Censorship:** A proof, given knowledge of secrets relating to 37 | an identity and that the identity commitment being included in the tree, that 38 | it is _always_ possible to generate a valid proof. 39 | 3. **No Double Signalling:** A proof that any attempt to signal twice using the 40 | same identity commitment will result in the equality of the corresponding 41 | nullifier hashes. 42 | 4. **No Unauthorized Signalling:** A proof that it is not possible to have the 43 | circuit accept a proof where the identity commitment generating that proof is 44 | not already included in the tree of identity commitments. 45 | 46 | -------------------------------------------------------------------------------- /go-circuit/poseidon.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/consensys/gnark/frontend" 5 | "github.com/reilabs/gnark-lean-extractor/abstractor" 6 | "math/big" 7 | ) 8 | 9 | func hex(s string) big.Int { 10 | var bi big.Int 11 | bi.SetString(s, 0) 12 | return bi 13 | } 14 | 15 | var MDS_2 = [][]frontend.Variable{ 16 | { 17 | hex("0x066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5"), 18 | hex("0x2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e8"), 19 | }, { 20 | hex("0x0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff9"), 21 | hex("0x1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c8"), 22 | }, 23 | } 24 | 25 | var CONSTANTS_2 = [][]frontend.Variable{ 26 | { 27 | hex("0x09c46e9ec68e9bd4fe1faaba294cba38a71aa177534cdd1b6c7dc0dbd0abd7a7"), 28 | hex("0x0c0356530896eec42a97ed937f3135cfc5142b3ae405b8343c1d83ffa604cb81"), 29 | }, { 30 | hex("0x1e28a1d935698ad1142e51182bb54cf4a00ea5aabd6268bd317ea977cc154a30"), 31 | hex("0x27af2d831a9d2748080965db30e298e40e5757c3e008db964cf9e2b12b91251f"), 32 | }, { 33 | hex("0x1e6f11ce60fc8f513a6a3cfe16ae175a41291462f214cd0879aaf43545b74e03"), 34 | hex("0x2a67384d3bbd5e438541819cb681f0be04462ed14c3613d8f719206268d142d3"), 35 | }, { 36 | hex("0x0b66fdf356093a611609f8e12fbfecf0b985e381f025188936408f5d5c9f45d0"), 37 | hex("0x012ee3ec1e78d470830c61093c2ade370b26c83cc5cebeeddaa6852dbdb09e21"), 38 | }, { 39 | hex("0x0252ba5f6760bfbdfd88f67f8175e3fd6cd1c431b099b6bb2d108e7b445bb1b9"), 40 | hex("0x179474cceca5ff676c6bec3cef54296354391a8935ff71d6ef5aeaad7ca932f1"), 41 | }, { 42 | hex("0x2c24261379a51bfa9228ff4a503fd4ed9c1f974a264969b37e1a2589bbed2b91"), 43 | hex("0x1cc1d7b62692e63eac2f288bd0695b43c2f63f5001fc0fc553e66c0551801b05"), 44 | }, { 45 | hex("0x255059301aada98bb2ed55f852979e9600784dbf17fbacd05d9eff5fd9c91b56"), 46 | hex("0x28437be3ac1cb2e479e1f5c0eccd32b3aea24234970a8193b11c29ce7e59efd9"), 47 | }, { 48 | hex("0x28216a442f2e1f711ca4fa6b53766eb118548da8fb4f78d4338762c37f5f2043"), 49 | hex("0x2c1f47cd17fa5adf1f39f4e7056dd03feee1efce03094581131f2377323482c9"), 50 | }, { 51 | hex("0x07abad02b7a5ebc48632bcc9356ceb7dd9dafca276638a63646b8566a621afc9"), 52 | hex("0x0230264601ffdf29275b33ffaab51dfe9429f90880a69cd137da0c4d15f96c3c"), 53 | }, { 54 | hex("0x1bc973054e51d905a0f168656497ca40a864414557ee289e717e5d66899aa0a9"), 55 | hex("0x2e1c22f964435008206c3157e86341edd249aff5c2d8421f2a6b22288f0a67fc"), 56 | }, { 57 | hex("0x1224f38df67c5378121c1d5f461bbc509e8ea1598e46c9f7a70452bc2bba86b8"), 58 | hex("0x02e4e69d8ba59e519280b4bd9ed0068fd7bfe8cd9dfeda1969d2989186cde20e"), 59 | }, { 60 | hex("0x1f1eccc34aaba0137f5df81fc04ff3ee4f19ee364e653f076d47e9735d98018e"), 61 | hex("0x1672ad3d709a353974266c3039a9a7311424448032cd1819eacb8a4d4284f582"), 62 | }, { 63 | hex("0x283e3fdc2c6e420c56f44af5192b4ae9cda6961f284d24991d2ed602df8c8fc7"), 64 | hex("0x1c2a3d120c550ecfd0db0957170fa013683751f8fdff59d6614fbd69ff394bcc"), 65 | }, { 66 | hex("0x216f84877aac6172f7897a7323456efe143a9a43773ea6f296cb6b8177653fbd"), 67 | hex("0x2c0d272becf2a75764ba7e8e3e28d12bceaa47ea61ca59a411a1f51552f94788"), 68 | }, { 69 | hex("0x16e34299865c0e28484ee7a74c454e9f170a5480abe0508fcb4a6c3d89546f43"), 70 | hex("0x175ceba599e96f5b375a232a6fb9cc71772047765802290f48cd939755488fc5"), 71 | }, { 72 | hex("0x0c7594440dc48c16fead9e1758b028066aa410bfbc354f54d8c5ffbb44a1ee32"), 73 | hex("0x1a3c29bc39f21bb5c466db7d7eb6fd8f760e20013ccf912c92479882d919fd8d"), 74 | }, { 75 | hex("0x0ccfdd906f3426e5c0986ea049b253400855d349074f5a6695c8eeabcd22e68f"), 76 | hex("0x14f6bc81d9f186f62bdb475ce6c9411866a7a8a3fd065b3ce0e699b67dd9e796"), 77 | }, { 78 | hex("0x0962b82789fb3d129702ca70b2f6c5aacc099810c9c495c888edeb7386b97052"), 79 | hex("0x1a880af7074d18b3bf20c79de25127bc13284ab01ef02575afef0c8f6a31a86d"), 80 | }, { 81 | hex("0x10cba18419a6a332cd5e77f0211c154b20af2924fc20ff3f4c3012bb7ae9311b"), 82 | hex("0x057e62a9a8f89b3ebdc76ba63a9eaca8fa27b7319cae3406756a2849f302f10d"), 83 | }, { 84 | hex("0x287c971de91dc0abd44adf5384b4988cb961303bbf65cff5afa0413b44280cee"), 85 | hex("0x21df3388af1687bbb3bca9da0cca908f1e562bc46d4aba4e6f7f7960e306891d"), 86 | }, { 87 | hex("0x1be5c887d25bce703e25cc974d0934cd789df8f70b498fd83eff8b560e1682b3"), 88 | hex("0x268da36f76e568fb68117175cea2cd0dd2cb5d42fda5acea48d59c2706a0d5c1"), 89 | }, { 90 | hex("0x0e17ab091f6eae50c609beaf5510ececc5d8bb74135ebd05bd06460cc26a5ed6"), 91 | hex("0x04d727e728ffa0a67aee535ab074a43091ef62d8cf83d270040f5caa1f62af40"), 92 | }, { 93 | hex("0x0ddbd7bf9c29341581b549762bc022ed33702ac10f1bfd862b15417d7e39ca6e"), 94 | hex("0x2790eb3351621752768162e82989c6c234f5b0d1d3af9b588a29c49c8789654b"), 95 | }, { 96 | hex("0x1e457c601a63b73e4471950193d8a570395f3d9ab8b2fd0984b764206142f9e9"), 97 | hex("0x21ae64301dca9625638d6ab2bbe7135ffa90ecd0c43ff91fc4c686fc46e091b0"), 98 | }, { 99 | hex("0x0379f63c8ce3468d4da293166f494928854be9e3432e09555858534eed8d350b"), 100 | hex("0x002d56420359d0266a744a080809e054ca0e4921a46686ac8c9f58a324c35049"), 101 | }, { 102 | hex("0x123158e5965b5d9b1d68b3cd32e10bbeda8d62459e21f4090fc2c5af963515a6"), 103 | hex("0x0be29fc40847a941661d14bbf6cbe0420fbb2b6f52836d4e60c80eb49cad9ec1"), 104 | }, { 105 | hex("0x1ac96991dec2bb0557716142015a453c36db9d859cad5f9a233802f24fdf4c1a"), 106 | hex("0x1596443f763dbcc25f4964fc61d23b3e5e12c9fa97f18a9251ca3355bcb0627e"), 107 | }, { 108 | hex("0x12e0bcd3654bdfa76b2861d4ec3aeae0f1857d9f17e715aed6d049eae3ba3212"), 109 | hex("0x0fc92b4f1bbea82b9ea73d4af9af2a50ceabac7f37154b1904e6c76c7cf964ba"), 110 | }, { 111 | hex("0x1f9c0b1610446442d6f2e592a8013f40b14f7c7722236f4f9c7e965233872762"), 112 | hex("0x0ebd74244ae72675f8cde06157a782f4050d914da38b4c058d159f643dbbf4d3"), 113 | }, { 114 | hex("0x2cb7f0ed39e16e9f69a9fafd4ab951c03b0671e97346ee397a839839dccfc6d1"), 115 | hex("0x1a9d6e2ecff022cc5605443ee41bab20ce761d0514ce526690c72bca7352d9bf"), 116 | }, { 117 | hex("0x2a115439607f335a5ea83c3bc44a9331d0c13326a9a7ba3087da182d648ec72f"), 118 | hex("0x23f9b6529b5d040d15b8fa7aee3e3410e738b56305cd44f29535c115c5a4c060"), 119 | }, { 120 | hex("0x05872c16db0f72a2249ac6ba484bb9c3a3ce97c16d58b68b260eb939f0e6e8a7"), 121 | hex("0x1300bdee08bb7824ca20fb80118075f40219b6151d55b5c52b624a7cdeddf6a7"), 122 | }, { 123 | hex("0x19b9b63d2f108e17e63817863a8f6c288d7ad29916d98cb1072e4e7b7d52b376"), 124 | hex("0x015bee1357e3c015b5bda237668522f613d1c88726b5ec4224a20128481b4f7f"), 125 | }, { 126 | hex("0x2953736e94bb6b9f1b9707a4f1615e4efe1e1ce4bab218cbea92c785b128ffd1"), 127 | hex("0x0b069353ba091618862f806180c0385f851b98d372b45f544ce7266ed6608dfc"), 128 | }, { 129 | hex("0x304f74d461ccc13115e4e0bcfb93817e55aeb7eb9306b64e4f588ac97d81f429"), 130 | hex("0x15bbf146ce9bca09e8a33f5e77dfe4f5aad2a164a4617a4cb8ee5415cde913fc"), 131 | }, { 132 | hex("0x0ab4dfe0c2742cde44901031487964ed9b8f4b850405c10ca9ff23859572c8c6"), 133 | hex("0x0e32db320a044e3197f45f7649a19675ef5eedfea546dea9251de39f9639779a"), 134 | }, { 135 | hex("0x0a1756aa1f378ca4b27635a78b6888e66797733a82774896a3078efa516da016"), 136 | hex("0x044c4a33b10f693447fd17177f952ef895e61d328f85efa94254d6a2a25d93ef"), 137 | }, { 138 | hex("0x2ed3611b725b8a70be655b537f66f700fe0879d79a496891d37b07b5466c4b8b"), 139 | hex("0x1f9ba4e8bab7ce42c8ecc3d722aa2e0eadfdeb9cfdd347b5d8339ea7120858aa"), 140 | }, { 141 | hex("0x1b233043052e8c288f7ee907a84e518aa38e82ac4502066db74056f865c5d3da"), 142 | hex("0x2431e1cc164bb8d074031ab72bd55b4c902053bfc0f14db0ca2f97b020875954"), 143 | }, { 144 | hex("0x082f934c91f5aac330cd6953a0a7db45a13e322097583319a791f273965801fd"), 145 | hex("0x2b9a0a223e7538b0a34be074315542a3c77245e2ae7cbe999ad6bb930c48997c"), 146 | }, { 147 | hex("0x0e1cd91edd2cfa2cceb85483b887a9be8164163e75a8a00eb0b589cc70214e7d"), 148 | hex("0x2e1eac0f2bfdfd63c951f61477e3698999774f19854d00f588d324601cebe2f9"), 149 | }, { 150 | hex("0x0cbfa95f37fb74060c76158e769d6d157345784d8efdb33c23d748115b500b83"), 151 | hex("0x08f05b3be923ed44d65ad49d8a61e9a676d991e3a77513d9980c232dfa4a4f84"), 152 | }, { 153 | hex("0x22719e2a070bcd0852bf8e21984d0443e7284925dc0758a325a2dd510c047ef6"), 154 | hex("0x041f596a9ee1cb2bc060f7fcc3a1ab4c7bdbf036119982c0f41f62b2f26830c0"), 155 | }, { 156 | hex("0x233fd35de1be520a87628eb06f6b1d4c021be1c2d0dc464a19fcdd0986b10f89"), 157 | hex("0x0524b46d1aa87a5e4325e0a423ebc810d31e078aa1b4707eefcb453c61c9c267"), 158 | }, { 159 | hex("0x2c34f424c81e5716ce47fcac894b85824227bb954b0f3199cc4486237c515211"), 160 | hex("0x0b5f2a4b63387819207effc2b5541fb72dd2025b5457cc97f33010327de4915e"), 161 | }, { 162 | hex("0x22207856082ccc54c5b72fe439d2cfd6c17435d2f57af6ceaefac41fe05c659f"), 163 | hex("0x24d57a8bf5da63fe4e24159b7f8950b5cdfb210194caf79f27854048ce2c8171"), 164 | }, { 165 | hex("0x0afab181fdd5e0583b371d75bd693f98374ad7097bb01a8573919bb23b79396e"), 166 | hex("0x2dba9b108f208772998a52efac7cbd5676c0057194c16c0bf16290d62b1128ee"), 167 | }, { 168 | hex("0x26349b66edb8b16f56f881c788f53f83cbb83de0bd592b255aff13e6bce420b3"), 169 | hex("0x25af7ce0e5e10357685e95f92339753ad81a56d28ecc193b235288a3e6f137db"), 170 | }, { 171 | hex("0x25b4ce7bd2294390c094d6a55edd68b970eed7aae88b2bff1f7c0187fe35011f"), 172 | hex("0x22c543f10f6c89ec387e53f1908a88e5de9cef28ebdf30b18cb9d54c1e02b631"), 173 | }, { 174 | hex("0x0236f93e7789c4724fc7908a9f191e1e425e906a919d7a34df668e74882f87a9"), 175 | hex("0x29350b401166ca010e7d27e37d05da99652bdae114eb01659cb497af980c4b52"), 176 | }, { 177 | hex("0x0eed787d65820d3f6bd31bbab547f75a65edb75d844ebb89ee1260916652363f"), 178 | hex("0x07cc1170f13b46f2036a753f520b3291fdcd0e99bd94297d1906f656f4de6fad"), 179 | }, { 180 | hex("0x22b939233b1d7205f49bcf613a3d30b1908786d7f9f5d10c2059435689e8acea"), 181 | hex("0x01451762a0aab81c8aad1dc8bc33e870740f083a5aa85438add650ace60ae5a6"), 182 | }, { 183 | hex("0x23506bb5d8727d4461fabf1025d46d1fe32eaa61dec7da57e704fec0892fce89"), 184 | hex("0x2e484c44e838aea0bac06ae3f71bdd092a3709531e1efea97f8bd68907355522"), 185 | }, { 186 | hex("0x0f4bc7d07ebafd64379e78c50bd2e42baf4a594545cedc2545418da26835b54c"), 187 | hex("0x1f4d3c8f6583e9e5fa76637862faaee851582388725df460e620996d50d8e74e"), 188 | }, { 189 | hex("0x093514e0c70711f82660d07be0e4a988fae02abc7b681d9153eb9bcb48fe7389"), 190 | hex("0x1adab0c8e2b3bad346699a2b5f3bc03643ee83ece47228f24a58e0a347e153d8"), 191 | }, { 192 | hex("0x1672b1726057d99dd14709ebb474641a378c1b94b8072bac1a22dbef9e80dad2"), 193 | hex("0x1dfd53d4576af2e38f44f53fdcab468cc5d8e2fae0acc4ee30d47b239b479c14"), 194 | }, { 195 | hex("0x0c6888a10b75b0f3a70a36263a37e17fe6d77d640f6fc3debc7f207753205c60"), 196 | hex("0x1addb933a65be77092b34a7e77d12fe8611a61e00ee6848b85091ecca9d1e508"), 197 | }, { 198 | hex("0x00d7540dcd268a845c10ae18d1de933cf638ff5425f0afff7935628e299d1791"), 199 | hex("0x140c0e42687e9ead01b2827a5664ca9c26fedde4acd99db1d316939d20b82c0e"), 200 | }, { 201 | hex("0x2f0c3a115d4317d191ba89b8d13d1806c20a0f9b24f8c5edc091e2ae56565984"), 202 | hex("0x0c4ee778ff7c14553006ed220cf9c81008a0cff670b22b82d8c538a1dc958c61"), 203 | }, { 204 | hex("0x1704f2766d46f82c3693f00440ccc3609424ed26c0acc66227c3d7485de74c69"), 205 | hex("0x2f2d19cc3ea5d78ea7a02c1b51d244abf0769c9f8544e40239b66fe9009c3cfa"), 206 | }, { 207 | hex("0x1ae03853b75fcaba5053f112e2a8e8dcdd7ee6cb9cfed9c7d6c766a806fc6629"), 208 | hex("0x0971aabf795241df51d131d0fa61aa5f3556921b2d6f014e4e41a86ddaf056d5"), 209 | }, { 210 | hex("0x1408c316e6014e1a91d4cf6b6e0de73eda624f8380df1c875f5c29f7bfe2f646"), 211 | hex("0x1667f3fe2edbe850248abe42b543093b6c89f1f773ef285341691f39822ef5bd"), 212 | }, { 213 | hex("0x13bf7c5d0d2c4376a48b0a03557cdf915b81718409e5c133424c69576500fe37"), 214 | hex("0x07620a6dfb0b6cec3016adf3d3533c24024b95347856b79719bc0ba743a62c2c"), 215 | }, { 216 | hex("0x1574c7ef0c43545f36a8ca08bdbdd8b075d2959e2f322b731675de3e1982b4d0"), 217 | hex("0x269e4b5b7a2eb21afd567970a717ceec5bd4184571c254fdc06e03a7ff8378f0"), 218 | }, 219 | } 220 | 221 | var MDS_3 = [][]frontend.Variable{ 222 | { 223 | hex("0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b"), 224 | hex("0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0"), 225 | hex("0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d"), 226 | }, 227 | { 228 | hex("0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771"), 229 | hex("0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23"), 230 | hex("0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa"), 231 | }, 232 | { 233 | hex("0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7"), 234 | hex("0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911"), 235 | hex("0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0"), 236 | }, 237 | } 238 | 239 | var CONSTANTS_3 = [][]frontend.Variable{ 240 | { 241 | hex("0x0ee9a592ba9a9518d05986d656f40c2114c4993c11bb29938d21d47304cd8e6e"), 242 | hex("0x00f1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864"), 243 | hex("0x08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5"), 244 | }, { 245 | hex("0x2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d0"), 246 | hex("0x2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf2"), 247 | hex("0x0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa"), 248 | }, { 249 | hex("0x28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d"), 250 | hex("0x2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78"), 251 | hex("0x234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc632"), 252 | }, { 253 | hex("0x15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428"), 254 | hex("0x0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6"), 255 | hex("0x1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c"), 256 | }, { 257 | hex("0x10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559"), 258 | hex("0x1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6"), 259 | hex("0x1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c8705"), 260 | }, { 261 | hex("0x04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d"), 262 | hex("0x0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828"), 263 | hex("0x099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b9"), 264 | }, { 265 | hex("0x052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6"), 266 | hex("0x0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc"), 267 | hex("0x119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd1"), 268 | }, { 269 | hex("0x03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09"), 270 | hex("0x2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565"), 271 | hex("0x005032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f9"), 272 | }, { 273 | hex("0x233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5"), 274 | hex("0x05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280"), 275 | hex("0x0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b"), 276 | }, { 277 | hex("0x2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0"), 278 | hex("0x1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460"), 279 | hex("0x12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc0"), 280 | }, { 281 | hex("0x0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e"), 282 | hex("0x037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448"), 283 | hex("0x05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f"), 284 | }, { 285 | hex("0x29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e"), 286 | hex("0x20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f"), 287 | hex("0x2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c887"), 288 | }, { 289 | hex("0x143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8"), 290 | hex("0x0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1"), 291 | hex("0x028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da53"), 292 | }, { 293 | hex("0x2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c"), 294 | hex("0x0081c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e"), 295 | hex("0x2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb38"), 296 | }, { 297 | hex("0x30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206"), 298 | hex("0x1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad"), 299 | hex("0x10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c"), 300 | }, { 301 | hex("0x2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef"), 302 | hex("0x1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91"), 303 | hex("0x07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a0"), 304 | }, { 305 | hex("0x21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750"), 306 | hex("0x2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e"), 307 | hex("0x2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e"), 308 | }, { 309 | hex("0x162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab"), 310 | hex("0x2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311"), 311 | hex("0x2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a"), 312 | }, { 313 | hex("0x1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9"), 314 | hex("0x204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529"), 315 | hex("0x0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c502"), 316 | }, { 317 | hex("0x174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54"), 318 | hex("0x1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef"), 319 | hex("0x066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a"), 320 | }, { 321 | hex("0x2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804"), 322 | hex("0x13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649"), 323 | hex("0x1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a"), 324 | }, { 325 | hex("0x00ef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1"), 326 | hex("0x0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3"), 327 | hex("0x29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba89"), 328 | }, { 329 | hex("0x2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be"), 330 | hex("0x1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1"), 331 | hex("0x151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c5"), 332 | }, { 333 | hex("0x04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100"), 334 | hex("0x13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967"), 335 | hex("0x01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e4"), 336 | }, { 337 | hex("0x2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02"), 338 | hex("0x1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646"), 339 | hex("0x041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d"), 340 | }, { 341 | hex("0x154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6"), 342 | hex("0x0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4"), 343 | hex("0x0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e"), 344 | }, { 345 | hex("0x06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626"), 346 | hex("0x0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb"), 347 | hex("0x04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e13"), 348 | }, { 349 | hex("0x2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758"), 350 | hex("0x123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef"), 351 | hex("0x2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e9"), 352 | }, { 353 | hex("0x0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d"), 354 | hex("0x12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2"), 355 | hex("0x21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a90035"), 356 | }, { 357 | hex("0x16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147"), 358 | hex("0x1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2"), 359 | hex("0x07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a"), 360 | }, { 361 | hex("0x05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc"), 362 | hex("0x20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f"), 363 | hex("0x04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db69"), 364 | }, { 365 | hex("0x27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a"), 366 | hex("0x2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1"), 367 | hex("0x1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b8"), 368 | }, { 369 | hex("0x15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a"), 370 | hex("0x1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785"), 371 | hex("0x25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c77"), 372 | }, { 373 | hex("0x15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67"), 374 | hex("0x2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727"), 375 | hex("0x002e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b"), 376 | }, { 377 | hex("0x2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2"), 378 | hex("0x00b9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe"), 379 | hex("0x0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c3512"), 380 | }, { 381 | hex("0x00248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d"), 382 | hex("0x171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9"), 383 | hex("0x170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a808"), 384 | }, { 385 | hex("0x29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1"), 386 | hex("0x1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973"), 387 | hex("0x1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f09"), 388 | }, { 389 | hex("0x22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38"), 390 | hex("0x0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd"), 391 | hex("0x11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e8284"), 392 | }, { 393 | hex("0x1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af"), 394 | hex("0x2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466"), 395 | hex("0x3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad"), 396 | }, { 397 | hex("0x2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086"), 398 | hex("0x119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3"), 399 | hex("0x1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd800"), 400 | }, { 401 | hex("0x28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6"), 402 | hex("0x083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7"), 403 | hex("0x0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b"), 404 | }, { 405 | hex("0x0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b"), 406 | hex("0x2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591"), 407 | hex("0x0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f178"), 408 | }, { 409 | hex("0x0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40"), 410 | hex("0x1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4"), 411 | hex("0x0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e504233"), 412 | }, { 413 | hex("0x0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873"), 414 | hex("0x1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d"), 415 | hex("0x2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc0"), 416 | }, { 417 | hex("0x1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb"), 418 | hex("0x01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875"), 419 | hex("0x1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e"), 420 | }, { 421 | hex("0x2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019"), 422 | hex("0x23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b"), 423 | hex("0x2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d59"), 424 | }, { 425 | hex("0x0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f"), 426 | hex("0x2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8"), 427 | hex("0x15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f88948"), 428 | }, { 429 | hex("0x193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f"), 430 | hex("0x2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f"), 431 | hex("0x1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d142"), 432 | }, { 433 | hex("0x04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b"), 434 | hex("0x0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23"), 435 | hex("0x058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c0"), 436 | }, { 437 | hex("0x1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a"), 438 | hex("0x03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5"), 439 | hex("0x23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a58"), 440 | }, { 441 | hex("0x0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2"), 442 | hex("0x06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b"), 443 | hex("0x118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d01"), 444 | }, { 445 | hex("0x13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1"), 446 | hex("0x169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b"), 447 | hex("0x04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d"), 448 | }, { 449 | hex("0x256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec"), 450 | hex("0x30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2"), 451 | hex("0x10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc792"), 452 | }, { 453 | hex("0x193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860"), 454 | hex("0x18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d"), 455 | hex("0x29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea6111"), 456 | }, { 457 | hex("0x10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711"), 458 | hex("0x0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb"), 459 | hex("0x16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa336"), 460 | }, { 461 | hex("0x0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a"), 462 | hex("0x1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860"), 463 | hex("0x0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d6"), 464 | }, { 465 | hex("0x161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b"), 466 | hex("0x0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b"), 467 | hex("0x1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f451"), 468 | }, { 469 | hex("0x2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556"), 470 | hex("0x1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70"), 471 | hex("0x2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf77"), 472 | }, { 473 | hex("0x23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea"), 474 | hex("0x09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d"), 475 | hex("0x188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc630"), 476 | }, { 477 | hex("0x3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f"), 478 | hex("0x15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78"), 479 | hex("0x1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc"), 480 | }, { 481 | hex("0x2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb"), 482 | hex("0x202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60"), 483 | hex("0x096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f"), 484 | }, { 485 | hex("0x054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4"), 486 | hex("0x1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1"), 487 | hex("0x21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc"), 488 | }, { 489 | hex("0x1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08"), 490 | hex("0x0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100"), 491 | hex("0x1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c2320"), 492 | }, { 493 | hex("0x0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870"), 494 | hex("0x193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba"), 495 | hex("0x102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f8"), 496 | }, { 497 | hex("0x0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1"), 498 | hex("0x216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22"), 499 | hex("0x1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e4228325161"), 500 | }, 501 | } 502 | 503 | type cfg struct { 504 | RF int 505 | RP int 506 | constants [][]frontend.Variable 507 | mds [][]frontend.Variable 508 | } 509 | 510 | var CFG_3 = cfg{ 511 | RF: 8, 512 | RP: 57, 513 | constants: CONSTANTS_3, 514 | mds: MDS_3, 515 | } 516 | 517 | var CFG_2 = cfg{ 518 | RF: 8, 519 | RP: 56, 520 | constants: CONSTANTS_2, 521 | mds: MDS_2, 522 | } 523 | 524 | func cfgFor(t int) *cfg { 525 | switch t { 526 | case 2: 527 | return &CFG_2 528 | case 3: 529 | return &CFG_3 530 | } 531 | panic("Poseidon: unsupported arg count") 532 | } 533 | 534 | type Poseidon1 struct { 535 | In frontend.Variable 536 | } 537 | 538 | func (g Poseidon1) DefineGadget(api abstractor.API) []frontend.Variable { 539 | inp := []frontend.Variable{0, g.In} 540 | return api.Call(poseidon{inp})[:1] 541 | } 542 | 543 | type Poseidon2 struct { 544 | In1, In2 frontend.Variable 545 | } 546 | 547 | func (g Poseidon2) DefineGadget(api abstractor.API) []frontend.Variable { 548 | inp := []frontend.Variable{0, g.In1, g.In2} 549 | return api.Call(poseidon{inp})[:1] 550 | } 551 | 552 | type poseidon struct { 553 | Inputs []frontend.Variable 554 | } 555 | 556 | func (g poseidon) DefineGadget(api abstractor.API) []frontend.Variable { 557 | state := g.Inputs 558 | cfg := cfgFor(len(state)) 559 | for i := 0; i < cfg.RF/2; i += 1 { 560 | state = api.Call(fullRound{state, cfg.constants[i]}) 561 | } 562 | for i := 0; i < cfg.RP; i += 1 { 563 | state = api.Call(halfRound{state, cfg.constants[cfg.RF/2+i]}) 564 | } 565 | for i := 0; i < cfg.RF/2; i += 1 { 566 | state = api.Call(fullRound{state, cfg.constants[cfg.RF/2+cfg.RP+i]}) 567 | } 568 | return state 569 | } 570 | 571 | type sbox struct { 572 | Inp frontend.Variable 573 | } 574 | 575 | func (s sbox) DefineGadget(api abstractor.API) []frontend.Variable { 576 | v2 := api.Mul(s.Inp, s.Inp) 577 | v4 := api.Mul(v2, v2) 578 | r := api.Mul(s.Inp, v4) 579 | return []frontend.Variable{r} 580 | } 581 | 582 | type mds struct { 583 | Inp []frontend.Variable 584 | } 585 | 586 | func (m mds) DefineGadget(api abstractor.API) []frontend.Variable { 587 | var mds = make([]frontend.Variable, len(m.Inp)) 588 | cfg := cfgFor(len(m.Inp)) 589 | for i := 0; i < len(m.Inp); i += 1 { 590 | var sum frontend.Variable = 0 591 | for j := 0; j < len(m.Inp); j += 1 { 592 | sum = api.Add(sum, api.Mul(m.Inp[j], cfg.mds[i][j])) 593 | } 594 | mds[i] = sum 595 | } 596 | return mds 597 | } 598 | 599 | type halfRound struct { 600 | Inp []frontend.Variable 601 | Consts []frontend.Variable 602 | } 603 | 604 | func (h halfRound) DefineGadget(api abstractor.API) []frontend.Variable { 605 | for i := 0; i < len(h.Inp); i += 1 { 606 | h.Inp[i] = api.Add(h.Inp[i], h.Consts[i]) 607 | } 608 | h.Inp[0] = api.Call(sbox{h.Inp[0]})[0] 609 | return api.Call(mds{h.Inp}) 610 | } 611 | 612 | type fullRound struct { 613 | Inp []frontend.Variable 614 | Consts []frontend.Variable 615 | } 616 | 617 | func (h fullRound) DefineGadget(api abstractor.API) []frontend.Variable { 618 | for i := 0; i < len(h.Inp); i += 1 { 619 | h.Inp[i] = api.Add(h.Inp[i], h.Consts[i]) 620 | } 621 | for i := 0; i < len(h.Inp); i += 1 { 622 | h.Inp[i] = api.Call(sbox{h.Inp[i]})[0] 623 | } 624 | return api.Call(mds{h.Inp}) 625 | } 626 | -------------------------------------------------------------------------------- /go-circuit/semaphore.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "path/filepath" 7 | 8 | "github.com/reilabs/gnark-lean-extractor/abstractor" 9 | "github.com/reilabs/gnark-lean-extractor/extractor" 10 | 11 | "github.com/consensys/gnark-crypto/ecc" 12 | "github.com/consensys/gnark/frontend" 13 | 14 | "github.com/urfave/cli/v2" 15 | ) 16 | 17 | type MerkleTreeRecoverRound struct { 18 | Direction frontend.Variable 19 | Hash frontend.Variable 20 | Sibling frontend.Variable 21 | } 22 | 23 | func (gadget MerkleTreeRecoverRound) DefineGadget(api abstractor.API) []frontend.Variable { 24 | api.AssertIsBoolean(gadget.Direction) 25 | leftHash := api.Call(Poseidon2{gadget.Hash, gadget.Sibling})[0] 26 | rightHash := api.Call(Poseidon2{gadget.Sibling, gadget.Hash})[0] 27 | parent_hash := api.Select(gadget.Direction, rightHash, leftHash) 28 | return []frontend.Variable{parent_hash} 29 | } 30 | 31 | type MerkleTreeInclusionProof struct { 32 | Leaf frontend.Variable 33 | PathIndices []frontend.Variable 34 | Siblings []frontend.Variable 35 | } 36 | 37 | func (gadget MerkleTreeInclusionProof) DefineGadget(api abstractor.API) []frontend.Variable { 38 | levels := len(gadget.PathIndices) 39 | hashes := make([]frontend.Variable, levels+1) 40 | 41 | hashes[0] = gadget.Leaf 42 | for i := 0; i < levels; i++ { 43 | hashes[i+1] = api.Call(MerkleTreeRecoverRound{gadget.PathIndices[i], hashes[i], gadget.Siblings[i]})[0] 44 | } 45 | root := hashes[levels] 46 | return []frontend.Variable{root} 47 | } 48 | 49 | type Semaphore struct { 50 | IdentityNullifier frontend.Variable `gnark:",secret"` 51 | IdentityTrapdoor frontend.Variable `gnark:",secret"` 52 | TreePathIndices []frontend.Variable `gnark:",secret"` // 0 | 1 53 | TreeSiblings []frontend.Variable `gnark:",secret"` 54 | 55 | SignalHash frontend.Variable `gnark:",public"` 56 | ExternalNullifier frontend.Variable `gnark:",public"` 57 | 58 | // Outputs to check 59 | NullifierHash frontend.Variable `gnark:",public"` 60 | MTRoot frontend.Variable `gnark:",public"` 61 | 62 | // Parameters 63 | Levels int 64 | } 65 | 66 | func (circuit *Semaphore) AbsDefine(api abstractor.API) error { 67 | // From https://github.com/semaphore-protocol/semaphore/blob/main/packages/circuits/semaphore.circom 68 | 69 | secret := api.Call(Poseidon2{circuit.IdentityNullifier, circuit.IdentityTrapdoor})[0] 70 | identity_commitment := api.Call(Poseidon1{secret})[0] 71 | nullifierHash := api.Call(Poseidon2{circuit.ExternalNullifier, circuit.IdentityNullifier})[0] 72 | api.AssertIsEqual(nullifierHash, circuit.NullifierHash) // Verify 73 | 74 | root := api.Call(MerkleTreeInclusionProof{ 75 | Leaf: identity_commitment, 76 | PathIndices: circuit.TreePathIndices, 77 | Siblings: circuit.TreeSiblings, 78 | })[0] 79 | 80 | api.AssertIsEqual(root, circuit.MTRoot) // Verify 81 | api.Mul(circuit.SignalHash, circuit.SignalHash) 82 | 83 | return nil 84 | } 85 | 86 | func (circuit Semaphore) Define(api frontend.API) error { 87 | return abstractor.Concretize(api, &circuit) 88 | } 89 | 90 | func TestSemaphore() (string, error) { 91 | nLevels := 20 92 | assignment := Semaphore{ 93 | Levels: nLevels, 94 | TreePathIndices: make([]frontend.Variable, nLevels), 95 | TreeSiblings: make([]frontend.Variable, nLevels), 96 | } 97 | if len(assignment.TreePathIndices) != len(assignment.TreeSiblings) { 98 | panic("TreePathIndices and TreeSiblings must have the same length.") 99 | } 100 | return extractor.CircuitToLean(&assignment, ecc.BN254) 101 | } 102 | 103 | func main() { 104 | var out_file string 105 | 106 | app := &cli.App{ 107 | Name: "gnark-lean-demo", 108 | Usage: "gnark to lean circuit extractor", 109 | Commands: []*cli.Command{ 110 | { 111 | Name: "extract-circuit", 112 | Aliases: []string{"e"}, 113 | Usage: "Extract circuit to file", 114 | Flags: []cli.Flag{ 115 | &cli.StringFlag{ 116 | Name: "out", 117 | Usage: "Load configuration from `FILE`", 118 | Required: true, 119 | Destination: &out_file, 120 | }, 121 | }, 122 | Action: func(cCtx *cli.Context) error { 123 | circuit_string, err := TestSemaphore() 124 | if err != nil { 125 | log.Fatal(err) 126 | } 127 | absPath, _ := filepath.Abs(out_file) 128 | err = os.MkdirAll(filepath.Dir(absPath), 0666) 129 | if err != nil && !os.IsExist(err) { 130 | log.Fatal(err) 131 | } 132 | err = os.WriteFile(absPath, []byte(circuit_string), 0666) 133 | if err != nil { 134 | log.Fatal(err) 135 | } 136 | return nil 137 | }, 138 | }, 139 | }, 140 | } 141 | 142 | if err := app.Run(os.Args); err != nil { 143 | log.Fatal(err) 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/reilabs/gnark-lean-demo 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/consensys/gnark v0.8.0 7 | github.com/consensys/gnark-crypto v0.9.1 8 | github.com/reilabs/gnark-lean-extractor v1.0.0 9 | github.com/urfave/cli/v2 v2.25.7 10 | ) 11 | 12 | require ( 13 | github.com/blang/semver/v4 v4.0.0 // indirect 14 | github.com/consensys/bavard v0.1.13 // indirect 15 | github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect 16 | github.com/mattn/go-colorable v0.1.12 // indirect 17 | github.com/mattn/go-isatty v0.0.14 // indirect 18 | github.com/mmcloughlin/addchain v0.4.0 // indirect 19 | github.com/rs/zerolog v1.29.0 // indirect 20 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 21 | github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect 22 | golang.org/x/sys v0.5.0 // indirect 23 | rsc.io/tmplfunc v0.0.3 // indirect 24 | ) 25 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= 2 | github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= 3 | github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= 4 | github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= 5 | github.com/consensys/gnark v0.8.0 h1:0bQ2MyDG4oNjMQpNyL8HjrrUSSL3yYJg0Elzo6LzmcU= 6 | github.com/consensys/gnark v0.8.0/go.mod h1:aKmA7dIiLbTm0OV37xTq0z+Bpe4xER8EhRLi6necrm8= 7 | github.com/consensys/gnark-crypto v0.9.1 h1:mru55qKdWl3E035hAoh1jj9d7hVnYY5pfb6tmovSmII= 8 | github.com/consensys/gnark-crypto v0.9.1/go.mod h1:a2DQL4+5ywF6safEeZFEPGRiiGbjzGFRUN2sg06VuU4= 9 | github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 10 | github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= 11 | github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 12 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 13 | github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= 14 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 15 | github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= 16 | github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= 17 | github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= 18 | github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= 19 | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 20 | github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= 21 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 22 | github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= 23 | github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= 24 | github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= 25 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 26 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 27 | github.com/reilabs/gnark-lean-extractor v1.0.0 h1:jLoI4Dh3eAFdhJ3hvUfBmKJgB2NLPGrL7VW+WDRecCQ= 28 | github.com/reilabs/gnark-lean-extractor v1.0.0/go.mod h1:FuCRQ2kdpdImOzmzFUqMoCMQxn+Nol+AmzPDWlBZLA8= 29 | github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= 30 | github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= 31 | github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= 32 | github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= 33 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 34 | github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= 35 | github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= 36 | github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= 37 | github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= 38 | github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= 39 | github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= 40 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 41 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 42 | golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= 43 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 44 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 45 | rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= 46 | rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= 47 | -------------------------------------------------------------------------------- /lean-circuit/LeanCircuit.lean: -------------------------------------------------------------------------------- 1 | import ProvenZk.Gates 2 | import ProvenZk.Ext.Vector 3 | 4 | namespace Semaphore 5 | 6 | def Order : ℕ := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 7 | variable [Fact (Nat.Prime Order)] 8 | abbrev F := ZMod Order 9 | 10 | def sbox (Inp: F) (k: F -> Prop): Prop := 11 | ∃gate_0, gate_0 = Gates.mul Inp Inp ∧ 12 | ∃gate_1, gate_1 = Gates.mul gate_0 gate_0 ∧ 13 | ∃gate_2, gate_2 = Gates.mul Inp gate_1 ∧ 14 | k gate_2 15 | 16 | def mds_3 (Inp: Vector F 3) (k: Vector F 3 -> Prop): Prop := 17 | ∃gate_0, gate_0 = Gates.mul Inp[0] 7511745149465107256748700652201246547602992235352608707588321460060273774987 ∧ 18 | ∃gate_1, gate_1 = Gates.add 0 gate_0 ∧ 19 | ∃gate_2, gate_2 = Gates.mul Inp[1] 10370080108974718697676803824769673834027675643658433702224577712625900127200 ∧ 20 | ∃gate_3, gate_3 = Gates.add gate_1 gate_2 ∧ 21 | ∃gate_4, gate_4 = Gates.mul Inp[2] 19705173408229649878903981084052839426532978878058043055305024233888854471533 ∧ 22 | ∃gate_5, gate_5 = Gates.add gate_3 gate_4 ∧ 23 | ∃gate_6, gate_6 = Gates.mul Inp[0] 18732019378264290557468133440468564866454307626475683536618613112504878618481 ∧ 24 | ∃gate_7, gate_7 = Gates.add 0 gate_6 ∧ 25 | ∃gate_8, gate_8 = Gates.mul Inp[1] 20870176810702568768751421378473869562658540583882454726129544628203806653987 ∧ 26 | ∃gate_9, gate_9 = Gates.add gate_7 gate_8 ∧ 27 | ∃gate_10, gate_10 = Gates.mul Inp[2] 7266061498423634438633389053804536045105766754026813321943009179476902321146 ∧ 28 | ∃gate_11, gate_11 = Gates.add gate_9 gate_10 ∧ 29 | ∃gate_12, gate_12 = Gates.mul Inp[0] 9131299761947733513298312097611845208338517739621853568979632113419485819303 ∧ 30 | ∃gate_13, gate_13 = Gates.add 0 gate_12 ∧ 31 | ∃gate_14, gate_14 = Gates.mul Inp[1] 10595341252162738537912664445405114076324478519622938027420701542910180337937 ∧ 32 | ∃gate_15, gate_15 = Gates.add gate_13 gate_14 ∧ 33 | ∃gate_16, gate_16 = Gates.mul Inp[2] 11597556804922396090267472882856054602429588299176362916247939723151043581408 ∧ 34 | ∃gate_17, gate_17 = Gates.add gate_15 gate_16 ∧ 35 | k vec![gate_5, gate_11, gate_17] 36 | 37 | def fullRound_3_3 (Inp: Vector F 3) (Consts: Vector F 3) (k: Vector F 3 -> Prop): Prop := 38 | ∃gate_0, gate_0 = Gates.add Inp[0] Consts[0] ∧ 39 | ∃gate_1, gate_1 = Gates.add Inp[1] Consts[1] ∧ 40 | ∃gate_2, gate_2 = Gates.add Inp[2] Consts[2] ∧ 41 | sbox gate_0 fun gate_3 => 42 | sbox gate_1 fun gate_4 => 43 | sbox gate_2 fun gate_5 => 44 | mds_3 vec![gate_3, gate_4, gate_5] fun gate_6 => 45 | k vec![gate_6[0], gate_6[1], gate_6[2]] 46 | 47 | def halfRound_3_3 (Inp: Vector F 3) (Consts: Vector F 3) (k: Vector F 3 -> Prop): Prop := 48 | ∃gate_0, gate_0 = Gates.add Inp[0] Consts[0] ∧ 49 | ∃gate_1, gate_1 = Gates.add Inp[1] Consts[1] ∧ 50 | ∃gate_2, gate_2 = Gates.add Inp[2] Consts[2] ∧ 51 | sbox gate_0 fun gate_3 => 52 | mds_3 vec![gate_3, gate_1, gate_2] fun gate_4 => 53 | k vec![gate_4[0], gate_4[1], gate_4[2]] 54 | 55 | def poseidon_3 (Inputs: Vector F 3) (k: Vector F 3 -> Prop): Prop := 56 | fullRound_3_3 vec![Inputs[0], Inputs[1], Inputs[2]] vec![6745197990210204598374042828761989596302876299545964402857411729872131034734, 426281677759936592021316809065178817848084678679510574715894138690250139748, 4014188762916583598888942667424965430287497824629657219807941460227372577781] fun gate_0 => 57 | fullRound_3_3 vec![gate_0[0], gate_0[1], gate_0[2]] vec![21328925083209914769191926116470334003273872494252651254811226518870906634704, 19525217621804205041825319248827370085205895195618474548469181956339322154226, 1402547928439424661186498190603111095981986484908825517071607587179649375482] fun gate_1 => 58 | fullRound_3_3 vec![gate_1[0], gate_1[1], gate_1[2]] vec![18320863691943690091503704046057443633081959680694199244583676572077409194605, 17709820605501892134371743295301255810542620360751268064484461849423726103416, 15970119011175710804034336110979394557344217932580634635707518729185096681010] fun gate_2 => 59 | fullRound_3_3 vec![gate_2[0], gate_2[1], gate_2[2]] vec![9818625905832534778628436765635714771300533913823445439412501514317783880744, 6235167673500273618358172865171408902079591030551453531218774338170981503478, 12575685815457815780909564540589853169226710664203625668068862277336357031324] fun gate_3 => 60 | halfRound_3_3 vec![gate_3[0], gate_3[1], gate_3[2]] vec![7381963244739421891665696965695211188125933529845348367882277882370864309593, 14214782117460029685087903971105962785460806586237411939435376993762368956406, 13382692957873425730537487257409819532582973556007555550953772737680185788165] fun gate_4 => 61 | halfRound_3_3 vec![gate_4[0], gate_4[1], gate_4[2]] vec![2203881792421502412097043743980777162333765109810562102330023625047867378813, 2916799379096386059941979057020673941967403377243798575982519638429287573544, 4341714036313630002881786446132415875360643644216758539961571543427269293497] fun gate_5 => 62 | halfRound_3_3 vec![gate_5[0], gate_5[1], gate_5[2]] vec![2340590164268886572738332390117165591168622939528604352383836760095320678310, 5222233506067684445011741833180208249846813936652202885155168684515636170204, 7963328565263035669460582454204125526132426321764384712313576357234706922961] fun gate_6 => 63 | halfRound_3_3 vec![gate_6[0], gate_6[1], gate_6[2]] vec![1394121618978136816716817287892553782094854454366447781505650417569234586889, 20251767894547536128245030306810919879363877532719496013176573522769484883301, 141695147295366035069589946372747683366709960920818122842195372849143476473] fun gate_7 => 64 | halfRound_3_3 vec![gate_7[0], gate_7[1], gate_7[2]] vec![15919677773886738212551540894030218900525794162097204800782557234189587084981, 2616624285043480955310772600732442182691089413248613225596630696960447611520, 4740655602437503003625476760295930165628853341577914460831224100471301981787] fun gate_8 => 65 | halfRound_3_3 vec![gate_8[0], gate_8[1], gate_8[2]] vec![19201590924623513311141753466125212569043677014481753075022686585593991810752, 12116486795864712158501385780203500958268173542001460756053597574143933465696, 8481222075475748672358154589993007112877289817336436741649507712124418867136] fun gate_9 => 66 | halfRound_3_3 vec![gate_9[0], gate_9[1], gate_9[2]] vec![5181207870440376967537721398591028675236553829547043817076573656878024336014, 1576305643467537308202593927724028147293702201461402534316403041563704263752, 2555752030748925341265856133642532487884589978209403118872788051695546807407] fun gate_10 => 67 | halfRound_3_3 vec![gate_10[0], gate_10[1], gate_10[2]] vec![18840924862590752659304250828416640310422888056457367520753407434927494649454, 14593453114436356872569019099482380600010961031449147888385564231161572479535, 20826991704411880672028799007667199259549645488279985687894219600551387252871] fun gate_11 => 68 | halfRound_3_3 vec![gate_11[0], gate_11[1], gate_11[2]] vec![9159011389589751902277217485643457078922343616356921337993871236707687166408, 5605846325255071220412087261490782205304876403716989785167758520729893194481, 1148784255964739709393622058074925404369763692117037208398835319441214134867] fun gate_12 => 69 | halfRound_3_3 vec![gate_12[0], gate_12[1], gate_12[2]] vec![20945896491956417459309978192328611958993484165135279604807006821513499894540, 229312996389666104692157009189660162223783309871515463857687414818018508814, 21184391300727296923488439338697060571987191396173649012875080956309403646776] fun gate_13 => 70 | halfRound_3_3 vec![gate_13[0], gate_13[1], gate_13[2]] vec![21853424399738097885762888601689700621597911601971608617330124755808946442758, 12776298811140222029408960445729157525018582422120161448937390282915768616621, 7556638921712565671493830639474905252516049452878366640087648712509680826732] fun gate_14 => 71 | halfRound_3_3 vec![gate_14[0], gate_14[1], gate_14[2]] vec![19042212131548710076857572964084011858520620377048961573689299061399932349935, 12871359356889933725034558434803294882039795794349132643274844130484166679697, 3313271555224009399457959221795880655466141771467177849716499564904543504032] fun gate_15 => 72 | halfRound_3_3 vec![gate_15[0], gate_15[1], gate_15[2]] vec![15080780006046305940429266707255063673138269243146576829483541808378091931472, 21300668809180077730195066774916591829321297484129506780637389508430384679582, 20480395468049323836126447690964858840772494303543046543729776750771407319822] fun gate_16 => 73 | halfRound_3_3 vec![gate_16[0], gate_16[1], gate_16[2]] vec![10034492246236387932307199011778078115444704411143703430822959320969550003883, 19584962776865783763416938001503258436032522042569001300175637333222729790225, 20155726818439649091211122042505326538030503429443841583127932647435472711802] fun gate_17 => 74 | halfRound_3_3 vec![gate_17[0], gate_17[1], gate_17[2]] vec![13313554736139368941495919643765094930693458639277286513236143495391474916777, 14606609055603079181113315307204024259649959674048912770003912154260692161833, 5563317320536360357019805881367133322562055054443943486481491020841431450882] fun gate_18 => 75 | halfRound_3_3 vec![gate_18[0], gate_18[1], gate_18[2]] vec![10535419877021741166931390532371024954143141727751832596925779759801808223060, 12025323200952647772051708095132262602424463606315130667435888188024371598063, 2906495834492762782415522961458044920178260121151056598901462871824771097354] fun gate_19 => 76 | halfRound_3_3 vec![gate_19[0], gate_19[1], gate_19[2]] vec![19131970618309428864375891649512521128588657129006772405220584460225143887876, 8896386073442729425831367074375892129571226824899294414632856215758860965449, 7748212315898910829925509969895667732958278025359537472413515465768989125274] fun gate_20 => 77 | halfRound_3_3 vec![gate_20[0], gate_20[1], gate_20[2]] vec![422974903473869924285294686399247660575841594104291551918957116218939002865, 6398251826151191010634405259351528880538837895394722626439957170031528482771, 18978082967849498068717608127246258727629855559346799025101476822814831852169] fun gate_21 => 78 | halfRound_3_3 vec![gate_21[0], gate_21[1], gate_21[2]] vec![19150742296744826773994641927898928595714611370355487304294875666791554590142, 12896891575271590393203506752066427004153880610948642373943666975402674068209, 9546270356416926575977159110423162512143435321217584886616658624852959369669] fun gate_22 => 79 | halfRound_3_3 vec![gate_22[0], gate_22[1], gate_22[2]] vec![2159256158967802519099187112783460402410585039950369442740637803310736339200, 8911064487437952102278704807713767893452045491852457406400757953039127292263, 745203718271072817124702263707270113474103371777640557877379939715613501668] fun gate_23 => 80 | halfRound_3_3 vec![gate_23[0], gate_23[1], gate_23[2]] vec![19313999467876585876087962875809436559985619524211587308123441305315685710594, 13254105126478921521101199309550428567648131468564858698707378705299481802310, 1842081783060652110083740461228060164332599013503094142244413855982571335453] fun gate_24 => 81 | halfRound_3_3 vec![gate_24[0], gate_24[1], gate_24[2]] vec![9630707582521938235113899367442877106957117302212260601089037887382200262598, 5066637850921463603001689152130702510691309665971848984551789224031532240292, 4222575506342961001052323857466868245596202202118237252286417317084494678062] fun gate_25 => 82 | halfRound_3_3 vec![gate_25[0], gate_25[1], gate_25[2]] vec![2919565560395273474653456663643621058897649501626354982855207508310069954086, 6828792324689892364977311977277548750189770865063718432946006481461319858171, 2245543836264212411244499299744964607957732316191654500700776604707526766099] fun gate_26 => 83 | halfRound_3_3 vec![gate_26[0], gate_26[1], gate_26[2]] vec![19602444885919216544870739287153239096493385668743835386720501338355679311704, 8239538512351936341605373169291864076963368674911219628966947078336484944367, 15053013456316196458870481299866861595818749671771356646798978105863499965417] fun gate_27 => 84 | halfRound_3_3 vec![gate_27[0], gate_27[1], gate_27[2]] vec![7173615418515925804810790963571435428017065786053377450925733428353831789901, 8239211677777829016346247446855147819062679124993100113886842075069166957042, 15330855478780269194281285878526984092296288422420009233557393252489043181621] fun gate_28 => 85 | halfRound_3_3 vec![gate_28[0], gate_28[1], gate_28[2]] vec![10014883178425964324400942419088813432808659204697623248101862794157084619079, 14014440630268834826103915635277409547403899966106389064645466381170788813506, 3580284508947993352601712737893796312152276667249521401778537893620670305946] fun gate_29 => 86 | halfRound_3_3 vec![gate_29[0], gate_29[1], gate_29[2]] vec![2559754020964039399020874042785294258009596917335212876725104742182177996988, 14898657953331064524657146359621913343900897440154577299309964768812788279359, 2094037260225570753385567402013028115218264157081728958845544426054943497065] fun gate_30 => 87 | halfRound_3_3 vec![gate_30[0], gate_30[1], gate_30[2]] vec![18051086536715129874440142649831636862614413764019212222493256578581754875930, 21680659279808524976004872421382255670910633119979692059689680820959727969489, 13950668739013333802529221454188102772764935019081479852094403697438884885176] fun gate_31 => 88 | halfRound_3_3 vec![gate_31[0], gate_31[1], gate_31[2]] vec![9703845704528288130475698300068368924202959408694460208903346143576482802458, 12064310080154762977097567536495874701200266107682637369509532768346427148165, 16970760937630487134309762150133050221647250855182482010338640862111040175223] fun gate_32 => 89 | halfRound_3_3 vec![gate_32[0], gate_32[1], gate_32[2]] vec![9790997389841527686594908620011261506072956332346095631818178387333642218087, 16314772317774781682315680698375079500119933343877658265473913556101283387175, 82044870826814863425230825851780076663078706675282523830353041968943811739] fun gate_33 => 90 | halfRound_3_3 vec![gate_33[0], gate_33[1], gate_33[2]] vec![21696416499108261787701615667919260888528264686979598953977501999747075085778, 327771579314982889069767086599893095509690747425186236545716715062234528958, 4606746338794869835346679399457321301521448510419912225455957310754258695442] fun gate_34 => 91 | halfRound_3_3 vec![gate_34[0], gate_34[1], gate_34[2]] vec![64499140292086295251085369317820027058256893294990556166497635237544139149, 10455028514626281809317431738697215395754892241565963900707779591201786416553, 10421411526406559029881814534127830959833724368842872558146891658647152404488] fun gate_35 => 92 | halfRound_3_3 vec![gate_35[0], gate_35[1], gate_35[2]] vec![18848084335930758908929996602136129516563864917028006334090900573158639401697, 13844582069112758573505569452838731733665881813247931940917033313637916625267, 13488838454403536473492810836925746129625931018303120152441617863324950564617] fun gate_36 => 93 | halfRound_3_3 vec![gate_36[0], gate_36[1], gate_36[2]] vec![15742141787658576773362201234656079648895020623294182888893044264221895077688, 6756884846734501741323584200608866954194124526254904154220230538416015199997, 7860026400080412708388991924996537435137213401947704476935669541906823414404] fun gate_37 => 94 | halfRound_3_3 vec![gate_37[0], gate_37[1], gate_37[2]] vec![7871040688194276447149361970364037034145427598711982334898258974993423182255, 20758972836260983284101736686981180669442461217558708348216227791678564394086, 21723241881201839361054939276225528403036494340235482225557493179929400043949] fun gate_38 => 95 | halfRound_3_3 vec![gate_38[0], gate_38[1], gate_38[2]] vec![19428469330241922173653014973246050805326196062205770999171646238586440011910, 7969200143746252148180468265998213908636952110398450526104077406933642389443, 10950417916542216146808986264475443189195561844878185034086477052349738113024] fun gate_39 => 96 | halfRound_3_3 vec![gate_39[0], gate_39[1], gate_39[2]] vec![18149233917533571579549129116652755182249709970669448788972210488823719849654, 3729796741814967444466779622727009306670204996071028061336690366291718751463, 5172504399789702452458550583224415301790558941194337190035441508103183388987] fun gate_40 => 97 | halfRound_3_3 vec![gate_40[0], gate_40[1], gate_40[2]] vec![6686473297578275808822003704722284278892335730899287687997898239052863590235, 19426913098142877404613120616123695099909113097119499573837343516470853338513, 5120337081764243150760446206763109494847464512045895114970710519826059751800] fun gate_41 => 98 | halfRound_3_3 vec![gate_41[0], gate_41[1], gate_41[2]] vec![5055737465570446530938379301905385631528718027725177854815404507095601126720, 14235578612970484492268974539959119923625505766550088220840324058885914976980, 653592517890187950103239281291172267359747551606210609563961204572842639923] fun gate_42 => 99 | halfRound_3_3 vec![gate_42[0], gate_42[1], gate_42[2]] vec![5507360526092411682502736946959369987101940689834541471605074817375175870579, 7864202866011437199771472205361912625244234597659755013419363091895334445453, 21294659996736305811805196472076519801392453844037698272479731199885739891648] fun gate_43 => 100 | halfRound_3_3 vec![gate_43[0], gate_43[1], gate_43[2]] vec![13767183507040326119772335839274719411331242166231012705169069242737428254651, 810181532076738148308457416289197585577119693706380535394811298325092337781, 14232321930654703053193240133923161848171310212544136614525040874814292190478] fun gate_44 => 101 | halfRound_3_3 vec![gate_44[0], gate_44[1], gate_44[2]] vec![16796904728299128263054838299534612533844352058851230375569421467352578781209, 16256310366973209550759123431979563367001604350120872788217761535379268327259, 19791658638819031543640174069980007021961272701723090073894685478509001321817] fun gate_45 => 102 | halfRound_3_3 vec![gate_45[0], gate_45[1], gate_45[2]] vec![7046232469803978873754056165670086532908888046886780200907660308846356865119, 16001732848952745747636754668380555263330934909183814105655567108556497219752, 9737276123084413897604802930591512772593843242069849260396983774140735981896] fun gate_46 => 103 | halfRound_3_3 vec![gate_46[0], gate_46[1], gate_46[2]] vec![11410895086919039954381533622971292904413121053792570364694836768885182251535, 19098362474249267294548762387533474746422711206129028436248281690105483603471, 11013788190750472643548844759298623898218957233582881400726340624764440203586] fun gate_47 => 104 | halfRound_3_3 vec![gate_47[0], gate_47[1], gate_47[2]] vec![2206958256327295151076063922661677909471794458896944583339625762978736821035, 7171889270225471948987523104033632910444398328090760036609063776968837717795, 2510237900514902891152324520472140114359583819338640775472608119384714834368] fun gate_48 => 105 | halfRound_3_3 vec![gate_48[0], gate_48[1], gate_48[2]] vec![8825275525296082671615660088137472022727508654813239986303576303490504107418, 1481125575303576470988538039195271612778457110700618040436600537924912146613, 16268684562967416784133317570130804847322980788316762518215429249893668424280] fun gate_49 => 106 | halfRound_3_3 vec![gate_49[0], gate_49[1], gate_49[2]] vec![4681491452239189664806745521067158092729838954919425311759965958272644506354, 3131438137839074317765338377823608627360421824842227925080193892542578675835, 7930402370812046914611776451748034256998580373012248216998696754202474945793] fun gate_50 => 107 | halfRound_3_3 vec![gate_50[0], gate_50[1], gate_50[2]] vec![8973151117361309058790078507956716669068786070949641445408234962176963060145, 10223139291409280771165469989652431067575076252562753663259473331031932716923, 2232089286698717316374057160056566551249777684520809735680538268209217819725] fun gate_51 => 108 | halfRound_3_3 vec![gate_51[0], gate_51[1], gate_51[2]] vec![16930089744400890347392540468934821520000065594669279286854302439710657571308, 21739597952486540111798430281275997558482064077591840966152905690279247146674, 7508315029150148468008716674010060103310093296969466203204862163743615534994] fun gate_52 => 109 | halfRound_3_3 vec![gate_52[0], gate_52[1], gate_52[2]] vec![11418894863682894988747041469969889669847284797234703818032750410328384432224, 10895338268862022698088163806301557188640023613155321294365781481663489837917, 18644184384117747990653304688839904082421784959872380449968500304556054962449] fun gate_53 => 110 | halfRound_3_3 vec![gate_53[0], gate_53[1], gate_53[2]] vec![7414443845282852488299349772251184564170443662081877445177167932875038836497, 5391299369598751507276083947272874512197023231529277107201098701900193273851, 10329906873896253554985208009869159014028187242848161393978194008068001342262] fun gate_54 => 111 | halfRound_3_3 vec![gate_54[0], gate_54[1], gate_54[2]] vec![4711719500416619550464783480084256452493890461073147512131129596065578741786, 11943219201565014805519989716407790139241726526989183705078747065985453201504, 4298705349772984837150885571712355513879480272326239023123910904259614053334] fun gate_55 => 112 | halfRound_3_3 vec![gate_55[0], gate_55[1], gate_55[2]] vec![9999044003322463509208400801275356671266978396985433172455084837770460579627, 4908416131442887573991189028182614782884545304889259793974797565686968097291, 11963412684806827200577486696316210731159599844307091475104710684559519773777] fun gate_56 => 113 | halfRound_3_3 vec![gate_56[0], gate_56[1], gate_56[2]] vec![20129916000261129180023520480843084814481184380399868943565043864970719708502, 12884788430473747619080473633364244616344003003135883061507342348586143092592, 20286808211545908191036106582330883564479538831989852602050135926112143921015] fun gate_57 => 114 | halfRound_3_3 vec![gate_57[0], gate_57[1], gate_57[2]] vec![16282045180030846845043407450751207026423331632332114205316676731302016331498, 4332932669439410887701725251009073017227450696965904037736403407953448682093, 11105712698773407689561953778861118250080830258196150686012791790342360778288] fun gate_58 => 115 | halfRound_3_3 vec![gate_58[0], gate_58[1], gate_58[2]] vec![21853934471586954540926699232107176721894655187276984175226220218852955976831, 9807888223112768841912392164376763820266226276821186661925633831143729724792, 13411808896854134882869416756427789378942943805153730705795307450368858622668] fun gate_59 => 116 | halfRound_3_3 vec![gate_59[0], gate_59[1], gate_59[2]] vec![17906847067500673080192335286161014930416613104209700445088168479205894040011, 14554387648466176616800733804942239711702169161888492380425023505790070369632, 4264116751358967409634966292436919795665643055548061693088119780787376143967] fun gate_60 => 117 | fullRound_3_3 vec![gate_60[0], gate_60[1], gate_60[2]] vec![2401104597023440271473786738539405349187326308074330930748109868990675625380, 12251645483867233248963286274239998200789646392205783056343767189806123148785, 15331181254680049984374210433775713530849624954688899814297733641575188164316] fun gate_61 => 118 | fullRound_3_3 vec![gate_61[0], gate_61[1], gate_61[2]] vec![13108834590369183125338853868477110922788848506677889928217413952560148766472, 6843160824078397950058285123048455551935389277899379615286104657075620692224, 10151103286206275742153883485231683504642432930275602063393479013696349676320] fun gate_62 => 119 | fullRound_3_3 vec![gate_62[0], gate_62[1], gate_62[2]] vec![7074320081443088514060123546121507442501369977071685257650287261047855962224, 11413928794424774638606755585641504971720734248726394295158115188173278890938, 7312756097842145322667451519888915975561412209738441762091369106604423801080] fun gate_63 => 120 | fullRound_3_3 vec![gate_63[0], gate_63[1], gate_63[2]] vec![7181677521425162567568557182629489303281861794357882492140051324529826589361, 15123155547166304758320442783720138372005699143801247333941013553002921430306, 13409242754315411433193860530743374419854094495153957441316635981078068351329] fun gate_64 => 121 | k vec![gate_64[0], gate_64[1], gate_64[2]] 122 | 123 | def Poseidon2 (In1: F) (In2: F) (k: F -> Prop): Prop := 124 | poseidon_3 vec![0, In1, In2] fun gate_0 => 125 | k gate_0[0] 126 | 127 | def mds_2 (Inp: Vector F 2) (k: Vector F 2 -> Prop): Prop := 128 | ∃gate_0, gate_0 = Gates.mul Inp[0] 2910766817845651019878574839501801340070030115151021261302834310722729507541 ∧ 129 | ∃gate_1, gate_1 = Gates.add 0 gate_0 ∧ 130 | ∃gate_2, gate_2 = Gates.mul Inp[1] 19727366863391167538122140361473584127147630672623100827934084310230022599144 ∧ 131 | ∃gate_3, gate_3 = Gates.add gate_1 gate_2 ∧ 132 | ∃gate_4, gate_4 = Gates.mul Inp[0] 5776684794125549462448597414050232243778680302179439492664047328281728356345 ∧ 133 | ∃gate_5, gate_5 = Gates.add 0 gate_4 ∧ 134 | ∃gate_6, gate_6 = Gates.mul Inp[1] 8348174920934122550483593999453880006756108121341067172388445916328941978568 ∧ 135 | ∃gate_7, gate_7 = Gates.add gate_5 gate_6 ∧ 136 | k vec![gate_3, gate_7] 137 | 138 | def fullRound_2_2 (Inp: Vector F 2) (Consts: Vector F 2) (k: Vector F 2 -> Prop): Prop := 139 | ∃gate_0, gate_0 = Gates.add Inp[0] Consts[0] ∧ 140 | ∃gate_1, gate_1 = Gates.add Inp[1] Consts[1] ∧ 141 | sbox gate_0 fun gate_2 => 142 | sbox gate_1 fun gate_3 => 143 | mds_2 vec![gate_2, gate_3] fun gate_4 => 144 | k vec![gate_4[0], gate_4[1]] 145 | 146 | def halfRound_2_2 (Inp: Vector F 2) (Consts: Vector F 2) (k: Vector F 2 -> Prop): Prop := 147 | ∃gate_0, gate_0 = Gates.add Inp[0] Consts[0] ∧ 148 | ∃gate_1, gate_1 = Gates.add Inp[1] Consts[1] ∧ 149 | sbox gate_0 fun gate_2 => 150 | mds_2 vec![gate_2, gate_1] fun gate_3 => 151 | k vec![gate_3[0], gate_3[1]] 152 | 153 | def poseidon_2 (Inputs: Vector F 2) (k: Vector F 2 -> Prop): Prop := 154 | fullRound_2_2 vec![Inputs[0], Inputs[1]] vec![4417881134626180770308697923359573201005643519861877412381846989312604493735, 5433650512959517612316327474713065966758808864213826738576266661723522780033] fun gate_0 => 155 | fullRound_2_2 vec![gate_0[0], gate_0[1]] vec![13641176377184356099764086973022553863760045607496549923679278773208775739952, 17949713444224994136330421782109149544629237834775211751417461773584374506783] fun gate_1 => 156 | fullRound_2_2 vec![gate_1[0], gate_1[1]] vec![13765628375339178273710281891027109699578766420463125835325926111705201856003, 19179513468172002314585757290678967643352171735526887944518845346318719730387] fun gate_2 => 157 | fullRound_2_2 vec![gate_2[0], gate_2[1]] vec![5157412437176756884543472904098424903141745259452875378101256928559722612176, 535160875740282236955320458485730000677124519901643397458212725410971557409] fun gate_3 => 158 | halfRound_2_2 vec![gate_3[0], gate_3[1]] vec![1050793453380762984940163090920066886770841063557081906093018330633089036729, 10665495010329663932664894101216428400933984666065399374198502106997623173873] fun gate_4 => 159 | halfRound_2_2 vec![gate_4[0], gate_4[1]] vec![19965634623406616956648724894636666805991993496469370618546874926025059150737, 13007250030070838431593222885902415182312449212965120303174723305710127422213] fun gate_5 => 160 | halfRound_2_2 vec![gate_5[0], gate_5[1]] vec![16877538715074991604507979123743768693428157847423939051086744213162455276374, 18211747749504876135588847560312685184956239426147543810126553367063157141465] fun gate_6 => 161 | halfRound_2_2 vec![gate_6[0], gate_6[1]] vec![18151553319826126919739798892854572062191241985315767086020821632812331245635, 19957033149976712666746140949846950406660099037474791840946955175819555930825] fun gate_7 => 162 | halfRound_2_2 vec![gate_7[0], gate_7[1]] vec![3469514863538261843186854830917934449567467100548474599735384052339577040841, 989698510043911779243192466312362856042600749099921773896924315611668507708] fun gate_8 => 163 | halfRound_2_2 vec![gate_8[0], gate_8[1]] vec![12568377015646290945235387813564567111330046038050864455358059568128000172201, 20856104135605479600325529349246932565148587186338606236677138505306779314172] fun gate_9 => 164 | halfRound_2_2 vec![gate_9[0], gate_9[1]] vec![8206918720503535523121349917159924938835810381723474192155637697065780938424, 1309058477013932989380617265069188723120054926187607548493110334522527703566] fun gate_10 => 165 | halfRound_2_2 vec![gate_10[0], gate_10[1]] vec![14076116939332667074621703729512195584105250395163383769419390236426287710606, 10153498892749751942204288991871286290442690932856658983589258153608012428674] fun gate_11 => 166 | halfRound_2_2 vec![gate_11[0], gate_11[1]] vec![18202499207234128286137597834010475797175973146805180988367589376893530181575, 12739388830157083522877690211447248168864006284243907142044329113461613743052] fun gate_12 => 167 | halfRound_2_2 vec![gate_12[0], gate_12[1]] vec![15123358710467780770838026754240340042441262572309759635224051333176022613949, 19925004701844594370904593774447343836015483888496504201331110250494635362184] fun gate_13 => 168 | halfRound_2_2 vec![gate_13[0], gate_13[1]] vec![10352416606816998476681131583320899030072315953910679608943150613208329645891, 10567371822366244361703342347428230537114808440249611395507235283708966113221] fun gate_14 => 169 | halfRound_2_2 vec![gate_14[0], gate_14[1]] vec![5635498582763880627392290206431559361272660937399944184533035305989295959602, 11866432933224219174041051738704352719163271639958083608224676028593315904909] fun gate_15 => 170 | halfRound_2_2 vec![gate_15[0], gate_15[1]] vec![5795020705294401441272215064554385591292330721703923167136157291459784140431, 9482202378699252817564375087302794636287866584767523335624368774856230692758] fun gate_16 => 171 | halfRound_2_2 vec![gate_16[0], gate_16[1]] vec![4245237636894546151746468406560945873445548423466753843402086544922216329298, 12000500941313982757584712677991730019124834399479314697467598397927435905133] fun gate_17 => 172 | halfRound_2_2 vec![gate_17[0], gate_17[1]] vec![7596790274058425558167520209857956363736666939016807569082239187494363541787, 2484867918246116343205467273440098378820186751202461278013576281097918148877] fun gate_18 => 173 | halfRound_2_2 vec![gate_18[0], gate_18[1]] vec![18312645949449997391810445935615409295369169383463185688973803378104013950190, 15320686572748723004980855263301182130424010735782762814513954166519592552733] fun gate_19 => 174 | halfRound_2_2 vec![gate_19[0], gate_19[1]] vec![12618438900597948888520621062416758747872180395546164387827245287017031303859, 17438141672027706116733201008397064011774368832458707512367404736905021019585] fun gate_20 => 175 | halfRound_2_2 vec![gate_20[0], gate_20[1]] vec![6374197807230665998865688675365359100400438034755781666913068586172586548950, 2189398913433273865510950346186699930188746169476472274335177556702504595264] fun gate_21 => 176 | halfRound_2_2 vec![gate_21[0], gate_21[1]] vec![6268495580028970231803791523870131137294646402347399003576649137450213034606, 17896250365994900261202920044129628104272791547990619503076839618914047059275] fun gate_22 => 177 | halfRound_2_2 vec![gate_22[0], gate_22[1]] vec![13692156312448722528008862371944543449350293305158722920787736248435893008873, 15234446864368744483209945022439268713300180233589581910497691316744177619376] fun gate_23 => 178 | halfRound_2_2 vec![gate_23[0], gate_23[1]] vec![1572426502623310766593681563281600503979671244997798691029595521622402217227, 80103447810215150918585162168214870083573048458555897999822831203653996617] fun gate_24 => 179 | halfRound_2_2 vec![gate_24[0], gate_24[1]] vec![8228820324013669567851850635126713973797711779951230446503353812192849106342, 5375851433746509614045812476958526065449377558695752132494533666370449415873] fun gate_25 => 180 | halfRound_2_2 vec![gate_25[0], gate_25[1]] vec![12115998939203497346386774317892338270561208357481805380546938146796257365018, 9764067909645821279940531410531154041386008396840887338272986634350423466622] fun gate_26 => 181 | halfRound_2_2 vec![gate_26[0], gate_26[1]] vec![8538708244538850542384936174629541085495830544298260335345008245230827876882, 7140127896620013355910287215441004676619168261422440177712039790284719613114] fun gate_27 => 182 | halfRound_2_2 vec![gate_27[0], gate_27[1]] vec![14297402962228458726038826185823085337698917275385741292940049024977027409762, 6667115556431351074165934212337261254608231545257434281887966406956835140819] fun gate_28 => 183 | halfRound_2_2 vec![gate_28[0], gate_28[1]] vec![20226761165244293291042617464655196752671169026542832236139342122602741090001, 12038289506489256655759141386763477208196694421666339040483042079632134429119] fun gate_29 => 184 | halfRound_2_2 vec![gate_29[0], gate_29[1]] vec![19027757334170818571203982241812412991528769934917288000224335655934473717551, 16272152964456553579565580463468069884359929612321610357528838696790370074720] fun gate_30 => 185 | halfRound_2_2 vec![gate_30[0], gate_30[1]] vec![2500392889689246014710135696485946334448570271481948765283016105301740284071, 8595254970528530312401637448610398388203855633951264114100575485022581946023] fun gate_31 => 186 | halfRound_2_2 vec![gate_31[0], gate_31[1]] vec![11635945688914011450976408058407206367914559009113158286982919675551688078198, 614739068603482619581328040478536306925147663946742687395148680260956671871] fun gate_32 => 187 | halfRound_2_2 vec![gate_32[0], gate_32[1]] vec![18692271780377861570175282183255720350972693125537599213951106550953176268753, 4987059230784976306647166378298632695585915319042844495357753339378260807164] fun gate_33 => 188 | halfRound_2_2 vec![gate_33[0], gate_33[1]] vec![21851403978498723616722415377430107676258664746210815234490134600998983955497, 9830635451186415300891533983087800047564037813328875992115573428596207326204] fun gate_34 => 189 | halfRound_2_2 vec![gate_34[0], gate_34[1]] vec![4842706106434537116860242620706030229206345167233200482994958847436425185478, 6422235064906823218421386871122109085799298052314922856340127798647926126490] fun gate_35 => 190 | halfRound_2_2 vec![gate_35[0], gate_35[1]] vec![4564364104986856861943331689105797031330091877115997069096365671501473357846, 1944043894089780613038197112872830569538541856657037469098448708685350671343] fun gate_36 => 191 | halfRound_2_2 vec![gate_36[0], gate_36[1]] vec![21179865974855950600518216085229498748425990426231530451599322283119880194955, 14296697761894107574369608843560006996183955751502547883167824879840894933162] fun gate_37 => 192 | halfRound_2_2 vec![gate_37[0], gate_37[1]] vec![12274619649702218570450581712439138337725246879938860735460378251639845671898, 16371396450276899401411886674029075408418848209575273031725505038938314070356] fun gate_38 => 193 | halfRound_2_2 vec![gate_38[0], gate_38[1]] vec![3702561221750983937578095019779188631407216522704543451228773892695044653565, 19721616877735564664624984774636557499099875603996426215495516594530838681980] fun gate_39 => 194 | halfRound_2_2 vec![gate_39[0], gate_39[1]] vec![6383350109027696789969911008057747025018308755462287526819231672217685282429, 20860583956177367265984596617324237471765572961978977333122281041544719622905] fun gate_40 => 195 | halfRound_2_2 vec![gate_40[0], gate_40[1]] vec![5766390934595026947545001478457407504285452477687752470140790011329357286275, 4043175758319898049344746138515323336207420888499903387536875603879441092484] fun gate_41 => 196 | halfRound_2_2 vec![gate_41[0], gate_41[1]] vec![15579382179133608217098622223834161692266188678101563820988612253342538956534, 1864640783252634743892105383926602930909039567065240010338908865509831749824] fun gate_42 => 197 | halfRound_2_2 vec![gate_42[0], gate_42[1]] vec![15943719865023133586707144161652035291705809358178262514871056013754142625673, 2326415993032390211558498780803238091925402878871059708106213703504162832999] fun gate_43 => 198 | halfRound_2_2 vec![gate_43[0], gate_43[1]] vec![19995326402773833553207196590622808505547443523750970375738981396588337910289, 5143583711361588952673350526320181330406047695593201009385718506918735286622] fun gate_44 => 199 | halfRound_2_2 vec![gate_44[0], gate_44[1]] vec![15436006486881920976813738625999473183944244531070780793506388892313517319583, 16660446760173633166698660166238066533278664023818938868110282615200613695857] fun gate_45 => 200 | halfRound_2_2 vec![gate_45[0], gate_45[1]] vec![4966065365695755376133119391352131079892396024584848298231004326013366253934, 20683781957411705574951987677641476019618457561419278856689645563561076926702] fun gate_46 => 201 | halfRound_2_2 vec![gate_46[0], gate_46[1]] vec![17280836839165902792086432296371645107551519324565649849400948918605456875699, 17045635513701208892073056357048619435743564064921155892004135325530808465371] fun gate_47 => 202 | halfRound_2_2 vec![gate_47[0], gate_47[1]] vec![17055032967194400710390142791334572297458033582458169295920670679093585707295, 15727174639569115300068198908071514334002742825679221638729902577962862163505] fun gate_48 => 203 | halfRound_2_2 vec![gate_48[0], gate_48[1]] vec![1001755657610446661315902885492677747789366510875120894840818704741370398633, 18638547332826171619311285502376343504539399518545103511265465604926625041234] fun gate_49 => 204 | halfRound_2_2 vec![gate_49[0], gate_49[1]] vec![6751954224763196429755298529194402870632445298969935050224267844020826420799, 3526747115904224771452549517614107688674036840088422555827581348280834879405] fun gate_50 => 205 | halfRound_2_2 vec![gate_50[0], gate_50[1]] vec![15705897908180497062880001271426561999724005008972544196300715293701537574122, 574386695213920937259007343820417029802510752426579750428758189312416867750] fun gate_51 => 206 | halfRound_2_2 vec![gate_51[0], gate_51[1]] vec![15973040855000600860816974646787367136127946402908768408978806375685439868553, 20934130413948796333037139460875996342810005558806621330680156931816867321122] fun gate_52 => 207 | halfRound_2_2 vec![gate_52[0], gate_52[1]] vec![6918585327145564636398173845411579411526758237572034236476079610890705810764, 14158163500813182062258176233162498241310167509137716527054939926126453647182] fun gate_53 => 208 | halfRound_2_2 vec![gate_53[0], gate_53[1]] vec![4164602626597695668474100217150111342272610479949122406544277384862187287433, 12146526846507496913615390662823936206892812880963914267275606265272996025304] fun gate_54 => 209 | halfRound_2_2 vec![gate_54[0], gate_54[1]] vec![10153527926900017763244212043512822363696541810586522108597162891799345289938, 13564663485965299104296214940873270349072051793008946663855767889066202733588] fun gate_55 => 210 | halfRound_2_2 vec![gate_55[0], gate_55[1]] vec![5612449256997576125867742696783020582952387615430650198777254717398552960096, 12151885480032032868507892738683067544172874895736290365318623681886999930120] fun gate_56 => 211 | halfRound_2_2 vec![gate_56[0], gate_56[1]] vec![380452237704664384810613424095477896605414037288009963200982915188629772177, 9067557551252570188533509616805287919563636482030947363841198066124642069518] fun gate_57 => 212 | halfRound_2_2 vec![gate_57[0], gate_57[1]] vec![21280306817619711661335268484199763923870315733198162896599997188206277056900, 5567165819557297006750252582140767993422097822227408837378089569369734876257] fun gate_58 => 213 | halfRound_2_2 vec![gate_58[0], gate_58[1]] vec![10411936321072105429908396649383171465939606386380071222095155850987201580137, 21338390051413922944780864872652000187403217966653363270851298678606449622266] fun gate_59 => 214 | fullRound_2_2 vec![gate_59[0], gate_59[1]] vec![12156296560457833712186127325312904760045212412680904475497938949653569234473, 4271647814574748734312113971565139132510281260328947438246615707172526380757] fun gate_60 => 215 | fullRound_2_2 vec![gate_60[0], gate_60[1]] vec![9061738206062369647211128232833114177054715885442782773131292534862178874950, 10134551893627587797380445583959894183158393780166496661696555422178052339133] fun gate_61 => 216 | fullRound_2_2 vec![gate_61[0], gate_61[1]] vec![8932270237664043612366044102088319242789325050842783721780970129656616386103, 3339412934966886386194449782756711637636784424032779155216609410591712750636] fun gate_62 => 217 | fullRound_2_2 vec![gate_62[0], gate_62[1]] vec![9704903972004596791086522314847373103670545861209569267884026709445485704400, 17467570179597572575614276429760169990940929887711661192333523245667228809456] fun gate_63 => 218 | k vec![gate_63[0], gate_63[1]] 219 | 220 | def Poseidon1 (In: F) (k: F -> Prop): Prop := 221 | poseidon_2 vec![0, In] fun gate_0 => 222 | k gate_0[0] 223 | 224 | def MerkleTreeRecoverRound (Direction: F) (Hash: F) (Sibling: F) (k: F -> Prop): Prop := 225 | Gates.is_bool Direction ∧ 226 | Poseidon2 Hash Sibling fun gate_1 => 227 | Poseidon2 Sibling Hash fun gate_2 => 228 | ∃gate_3, Gates.select Direction gate_2 gate_1 gate_3 ∧ 229 | k gate_3 230 | 231 | def MerkleTreeInclusionProof_20_20 (Leaf: F) (PathIndices: Vector F 20) (Siblings: Vector F 20) (k: F -> Prop): Prop := 232 | MerkleTreeRecoverRound PathIndices[0] Leaf Siblings[0] fun gate_0 => 233 | MerkleTreeRecoverRound PathIndices[1] gate_0 Siblings[1] fun gate_1 => 234 | MerkleTreeRecoverRound PathIndices[2] gate_1 Siblings[2] fun gate_2 => 235 | MerkleTreeRecoverRound PathIndices[3] gate_2 Siblings[3] fun gate_3 => 236 | MerkleTreeRecoverRound PathIndices[4] gate_3 Siblings[4] fun gate_4 => 237 | MerkleTreeRecoverRound PathIndices[5] gate_4 Siblings[5] fun gate_5 => 238 | MerkleTreeRecoverRound PathIndices[6] gate_5 Siblings[6] fun gate_6 => 239 | MerkleTreeRecoverRound PathIndices[7] gate_6 Siblings[7] fun gate_7 => 240 | MerkleTreeRecoverRound PathIndices[8] gate_7 Siblings[8] fun gate_8 => 241 | MerkleTreeRecoverRound PathIndices[9] gate_8 Siblings[9] fun gate_9 => 242 | MerkleTreeRecoverRound PathIndices[10] gate_9 Siblings[10] fun gate_10 => 243 | MerkleTreeRecoverRound PathIndices[11] gate_10 Siblings[11] fun gate_11 => 244 | MerkleTreeRecoverRound PathIndices[12] gate_11 Siblings[12] fun gate_12 => 245 | MerkleTreeRecoverRound PathIndices[13] gate_12 Siblings[13] fun gate_13 => 246 | MerkleTreeRecoverRound PathIndices[14] gate_13 Siblings[14] fun gate_14 => 247 | MerkleTreeRecoverRound PathIndices[15] gate_14 Siblings[15] fun gate_15 => 248 | MerkleTreeRecoverRound PathIndices[16] gate_15 Siblings[16] fun gate_16 => 249 | MerkleTreeRecoverRound PathIndices[17] gate_16 Siblings[17] fun gate_17 => 250 | MerkleTreeRecoverRound PathIndices[18] gate_17 Siblings[18] fun gate_18 => 251 | MerkleTreeRecoverRound PathIndices[19] gate_18 Siblings[19] fun gate_19 => 252 | k gate_19 253 | 254 | def circuit (IdentityNullifier: F) (IdentityTrapdoor: F) (TreePathIndices: Vector F 20) (TreeSiblings: Vector F 20) (SignalHash: F) (ExternalNullifier: F) (NullifierHash: F) (MTRoot: F): Prop := 255 | Poseidon2 IdentityNullifier IdentityTrapdoor fun gate_0 => 256 | Poseidon1 gate_0 fun gate_1 => 257 | Poseidon2 ExternalNullifier IdentityNullifier fun gate_2 => 258 | Gates.eq gate_2 NullifierHash ∧ 259 | MerkleTreeInclusionProof_20_20 gate_1 vec![TreePathIndices[0], TreePathIndices[1], TreePathIndices[2], TreePathIndices[3], TreePathIndices[4], TreePathIndices[5], TreePathIndices[6], TreePathIndices[7], TreePathIndices[8], TreePathIndices[9], TreePathIndices[10], TreePathIndices[11], TreePathIndices[12], TreePathIndices[13], TreePathIndices[14], TreePathIndices[15], TreePathIndices[16], TreePathIndices[17], TreePathIndices[18], TreePathIndices[19]] vec![TreeSiblings[0], TreeSiblings[1], TreeSiblings[2], TreeSiblings[3], TreeSiblings[4], TreeSiblings[5], TreeSiblings[6], TreeSiblings[7], TreeSiblings[8], TreeSiblings[9], TreeSiblings[10], TreeSiblings[11], TreeSiblings[12], TreeSiblings[13], TreeSiblings[14], TreeSiblings[15], TreeSiblings[16], TreeSiblings[17], TreeSiblings[18], TreeSiblings[19]] fun gate_4 => 260 | Gates.eq gate_4 MTRoot ∧ 261 | ∃_ignored_, _ignored_ = Gates.mul SignalHash SignalHash ∧ 262 | True 263 | 264 | end Semaphore -------------------------------------------------------------------------------- /lean-circuit/LeanCircuit/Poseidon/Constants.lean: -------------------------------------------------------------------------------- 1 | import Mathlib 2 | 3 | structure Constants where 4 | prime : Nat 5 | t : Nat 6 | t_ne_zero : t ≠ 0 7 | R_F : Nat 8 | R_P : Nat 9 | round_constants : List (ZMod prime) 10 | MDS_matrix : Matrix (Fin t) (Fin t) (ZMod prime) 11 | 12 | namespace Constants 13 | 14 | abbrev F (cfg : Constants) : Type := ZMod cfg.prime 15 | 16 | instance {cfg : Constants} : NeZero cfg.t := ⟨cfg.t_ne_zero⟩ 17 | 18 | def bn254_prime : Nat := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 19 | 20 | def x5_254_2_constants : List (ZMod bn254_prime) := [0x09c46e9ec68e9bd4fe1faaba294cba38a71aa177534cdd1b6c7dc0dbd0abd7a7, 0x0c0356530896eec42a97ed937f3135cfc5142b3ae405b8343c1d83ffa604cb81, 0x1e28a1d935698ad1142e51182bb54cf4a00ea5aabd6268bd317ea977cc154a30, 0x27af2d831a9d2748080965db30e298e40e5757c3e008db964cf9e2b12b91251f, 0x1e6f11ce60fc8f513a6a3cfe16ae175a41291462f214cd0879aaf43545b74e03, 0x2a67384d3bbd5e438541819cb681f0be04462ed14c3613d8f719206268d142d3, 0x0b66fdf356093a611609f8e12fbfecf0b985e381f025188936408f5d5c9f45d0, 0x012ee3ec1e78d470830c61093c2ade370b26c83cc5cebeeddaa6852dbdb09e21, 0x0252ba5f6760bfbdfd88f67f8175e3fd6cd1c431b099b6bb2d108e7b445bb1b9, 0x179474cceca5ff676c6bec3cef54296354391a8935ff71d6ef5aeaad7ca932f1, 0x2c24261379a51bfa9228ff4a503fd4ed9c1f974a264969b37e1a2589bbed2b91, 0x1cc1d7b62692e63eac2f288bd0695b43c2f63f5001fc0fc553e66c0551801b05, 0x255059301aada98bb2ed55f852979e9600784dbf17fbacd05d9eff5fd9c91b56, 0x28437be3ac1cb2e479e1f5c0eccd32b3aea24234970a8193b11c29ce7e59efd9, 0x28216a442f2e1f711ca4fa6b53766eb118548da8fb4f78d4338762c37f5f2043, 0x2c1f47cd17fa5adf1f39f4e7056dd03feee1efce03094581131f2377323482c9, 0x07abad02b7a5ebc48632bcc9356ceb7dd9dafca276638a63646b8566a621afc9, 0x0230264601ffdf29275b33ffaab51dfe9429f90880a69cd137da0c4d15f96c3c, 0x1bc973054e51d905a0f168656497ca40a864414557ee289e717e5d66899aa0a9, 0x2e1c22f964435008206c3157e86341edd249aff5c2d8421f2a6b22288f0a67fc, 0x1224f38df67c5378121c1d5f461bbc509e8ea1598e46c9f7a70452bc2bba86b8, 0x02e4e69d8ba59e519280b4bd9ed0068fd7bfe8cd9dfeda1969d2989186cde20e, 0x1f1eccc34aaba0137f5df81fc04ff3ee4f19ee364e653f076d47e9735d98018e, 0x1672ad3d709a353974266c3039a9a7311424448032cd1819eacb8a4d4284f582, 0x283e3fdc2c6e420c56f44af5192b4ae9cda6961f284d24991d2ed602df8c8fc7, 0x1c2a3d120c550ecfd0db0957170fa013683751f8fdff59d6614fbd69ff394bcc, 0x216f84877aac6172f7897a7323456efe143a9a43773ea6f296cb6b8177653fbd, 0x2c0d272becf2a75764ba7e8e3e28d12bceaa47ea61ca59a411a1f51552f94788, 0x16e34299865c0e28484ee7a74c454e9f170a5480abe0508fcb4a6c3d89546f43, 0x175ceba599e96f5b375a232a6fb9cc71772047765802290f48cd939755488fc5, 0x0c7594440dc48c16fead9e1758b028066aa410bfbc354f54d8c5ffbb44a1ee32, 0x1a3c29bc39f21bb5c466db7d7eb6fd8f760e20013ccf912c92479882d919fd8d, 0x0ccfdd906f3426e5c0986ea049b253400855d349074f5a6695c8eeabcd22e68f, 0x14f6bc81d9f186f62bdb475ce6c9411866a7a8a3fd065b3ce0e699b67dd9e796, 0x0962b82789fb3d129702ca70b2f6c5aacc099810c9c495c888edeb7386b97052, 0x1a880af7074d18b3bf20c79de25127bc13284ab01ef02575afef0c8f6a31a86d, 0x10cba18419a6a332cd5e77f0211c154b20af2924fc20ff3f4c3012bb7ae9311b, 0x057e62a9a8f89b3ebdc76ba63a9eaca8fa27b7319cae3406756a2849f302f10d, 0x287c971de91dc0abd44adf5384b4988cb961303bbf65cff5afa0413b44280cee, 0x21df3388af1687bbb3bca9da0cca908f1e562bc46d4aba4e6f7f7960e306891d, 0x1be5c887d25bce703e25cc974d0934cd789df8f70b498fd83eff8b560e1682b3, 0x268da36f76e568fb68117175cea2cd0dd2cb5d42fda5acea48d59c2706a0d5c1, 0x0e17ab091f6eae50c609beaf5510ececc5d8bb74135ebd05bd06460cc26a5ed6, 0x04d727e728ffa0a67aee535ab074a43091ef62d8cf83d270040f5caa1f62af40, 0x0ddbd7bf9c29341581b549762bc022ed33702ac10f1bfd862b15417d7e39ca6e, 0x2790eb3351621752768162e82989c6c234f5b0d1d3af9b588a29c49c8789654b, 0x1e457c601a63b73e4471950193d8a570395f3d9ab8b2fd0984b764206142f9e9, 0x21ae64301dca9625638d6ab2bbe7135ffa90ecd0c43ff91fc4c686fc46e091b0, 0x0379f63c8ce3468d4da293166f494928854be9e3432e09555858534eed8d350b, 0x002d56420359d0266a744a080809e054ca0e4921a46686ac8c9f58a324c35049, 0x123158e5965b5d9b1d68b3cd32e10bbeda8d62459e21f4090fc2c5af963515a6, 0x0be29fc40847a941661d14bbf6cbe0420fbb2b6f52836d4e60c80eb49cad9ec1, 0x1ac96991dec2bb0557716142015a453c36db9d859cad5f9a233802f24fdf4c1a, 0x1596443f763dbcc25f4964fc61d23b3e5e12c9fa97f18a9251ca3355bcb0627e, 0x12e0bcd3654bdfa76b2861d4ec3aeae0f1857d9f17e715aed6d049eae3ba3212, 0x0fc92b4f1bbea82b9ea73d4af9af2a50ceabac7f37154b1904e6c76c7cf964ba, 0x1f9c0b1610446442d6f2e592a8013f40b14f7c7722236f4f9c7e965233872762, 0x0ebd74244ae72675f8cde06157a782f4050d914da38b4c058d159f643dbbf4d3, 0x2cb7f0ed39e16e9f69a9fafd4ab951c03b0671e97346ee397a839839dccfc6d1, 0x1a9d6e2ecff022cc5605443ee41bab20ce761d0514ce526690c72bca7352d9bf, 0x2a115439607f335a5ea83c3bc44a9331d0c13326a9a7ba3087da182d648ec72f, 0x23f9b6529b5d040d15b8fa7aee3e3410e738b56305cd44f29535c115c5a4c060, 0x05872c16db0f72a2249ac6ba484bb9c3a3ce97c16d58b68b260eb939f0e6e8a7, 0x1300bdee08bb7824ca20fb80118075f40219b6151d55b5c52b624a7cdeddf6a7, 0x19b9b63d2f108e17e63817863a8f6c288d7ad29916d98cb1072e4e7b7d52b376, 0x015bee1357e3c015b5bda237668522f613d1c88726b5ec4224a20128481b4f7f, 0x2953736e94bb6b9f1b9707a4f1615e4efe1e1ce4bab218cbea92c785b128ffd1, 0x0b069353ba091618862f806180c0385f851b98d372b45f544ce7266ed6608dfc, 0x304f74d461ccc13115e4e0bcfb93817e55aeb7eb9306b64e4f588ac97d81f429, 0x15bbf146ce9bca09e8a33f5e77dfe4f5aad2a164a4617a4cb8ee5415cde913fc, 0x0ab4dfe0c2742cde44901031487964ed9b8f4b850405c10ca9ff23859572c8c6, 0x0e32db320a044e3197f45f7649a19675ef5eedfea546dea9251de39f9639779a, 0x0a1756aa1f378ca4b27635a78b6888e66797733a82774896a3078efa516da016, 0x044c4a33b10f693447fd17177f952ef895e61d328f85efa94254d6a2a25d93ef, 0x2ed3611b725b8a70be655b537f66f700fe0879d79a496891d37b07b5466c4b8b, 0x1f9ba4e8bab7ce42c8ecc3d722aa2e0eadfdeb9cfdd347b5d8339ea7120858aa, 0x1b233043052e8c288f7ee907a84e518aa38e82ac4502066db74056f865c5d3da, 0x2431e1cc164bb8d074031ab72bd55b4c902053bfc0f14db0ca2f97b020875954, 0x082f934c91f5aac330cd6953a0a7db45a13e322097583319a791f273965801fd, 0x2b9a0a223e7538b0a34be074315542a3c77245e2ae7cbe999ad6bb930c48997c, 0x0e1cd91edd2cfa2cceb85483b887a9be8164163e75a8a00eb0b589cc70214e7d, 0x2e1eac0f2bfdfd63c951f61477e3698999774f19854d00f588d324601cebe2f9, 0x0cbfa95f37fb74060c76158e769d6d157345784d8efdb33c23d748115b500b83, 0x08f05b3be923ed44d65ad49d8a61e9a676d991e3a77513d9980c232dfa4a4f84, 0x22719e2a070bcd0852bf8e21984d0443e7284925dc0758a325a2dd510c047ef6, 0x041f596a9ee1cb2bc060f7fcc3a1ab4c7bdbf036119982c0f41f62b2f26830c0, 0x233fd35de1be520a87628eb06f6b1d4c021be1c2d0dc464a19fcdd0986b10f89, 0x0524b46d1aa87a5e4325e0a423ebc810d31e078aa1b4707eefcb453c61c9c267, 0x2c34f424c81e5716ce47fcac894b85824227bb954b0f3199cc4486237c515211, 0x0b5f2a4b63387819207effc2b5541fb72dd2025b5457cc97f33010327de4915e, 0x22207856082ccc54c5b72fe439d2cfd6c17435d2f57af6ceaefac41fe05c659f, 0x24d57a8bf5da63fe4e24159b7f8950b5cdfb210194caf79f27854048ce2c8171, 0x0afab181fdd5e0583b371d75bd693f98374ad7097bb01a8573919bb23b79396e, 0x2dba9b108f208772998a52efac7cbd5676c0057194c16c0bf16290d62b1128ee, 0x26349b66edb8b16f56f881c788f53f83cbb83de0bd592b255aff13e6bce420b3, 0x25af7ce0e5e10357685e95f92339753ad81a56d28ecc193b235288a3e6f137db, 0x25b4ce7bd2294390c094d6a55edd68b970eed7aae88b2bff1f7c0187fe35011f, 0x22c543f10f6c89ec387e53f1908a88e5de9cef28ebdf30b18cb9d54c1e02b631, 0x0236f93e7789c4724fc7908a9f191e1e425e906a919d7a34df668e74882f87a9, 0x29350b401166ca010e7d27e37d05da99652bdae114eb01659cb497af980c4b52, 0x0eed787d65820d3f6bd31bbab547f75a65edb75d844ebb89ee1260916652363f, 0x07cc1170f13b46f2036a753f520b3291fdcd0e99bd94297d1906f656f4de6fad, 0x22b939233b1d7205f49bcf613a3d30b1908786d7f9f5d10c2059435689e8acea, 0x01451762a0aab81c8aad1dc8bc33e870740f083a5aa85438add650ace60ae5a6, 0x23506bb5d8727d4461fabf1025d46d1fe32eaa61dec7da57e704fec0892fce89, 0x2e484c44e838aea0bac06ae3f71bdd092a3709531e1efea97f8bd68907355522, 0x0f4bc7d07ebafd64379e78c50bd2e42baf4a594545cedc2545418da26835b54c, 0x1f4d3c8f6583e9e5fa76637862faaee851582388725df460e620996d50d8e74e, 0x093514e0c70711f82660d07be0e4a988fae02abc7b681d9153eb9bcb48fe7389, 0x1adab0c8e2b3bad346699a2b5f3bc03643ee83ece47228f24a58e0a347e153d8, 0x1672b1726057d99dd14709ebb474641a378c1b94b8072bac1a22dbef9e80dad2, 0x1dfd53d4576af2e38f44f53fdcab468cc5d8e2fae0acc4ee30d47b239b479c14, 0x0c6888a10b75b0f3a70a36263a37e17fe6d77d640f6fc3debc7f207753205c60, 0x1addb933a65be77092b34a7e77d12fe8611a61e00ee6848b85091ecca9d1e508, 0x00d7540dcd268a845c10ae18d1de933cf638ff5425f0afff7935628e299d1791, 0x140c0e42687e9ead01b2827a5664ca9c26fedde4acd99db1d316939d20b82c0e, 0x2f0c3a115d4317d191ba89b8d13d1806c20a0f9b24f8c5edc091e2ae56565984, 0x0c4ee778ff7c14553006ed220cf9c81008a0cff670b22b82d8c538a1dc958c61, 0x1704f2766d46f82c3693f00440ccc3609424ed26c0acc66227c3d7485de74c69, 0x2f2d19cc3ea5d78ea7a02c1b51d244abf0769c9f8544e40239b66fe9009c3cfa, 0x1ae03853b75fcaba5053f112e2a8e8dcdd7ee6cb9cfed9c7d6c766a806fc6629, 0x0971aabf795241df51d131d0fa61aa5f3556921b2d6f014e4e41a86ddaf056d5, 0x1408c316e6014e1a91d4cf6b6e0de73eda624f8380df1c875f5c29f7bfe2f646, 0x1667f3fe2edbe850248abe42b543093b6c89f1f773ef285341691f39822ef5bd, 0x13bf7c5d0d2c4376a48b0a03557cdf915b81718409e5c133424c69576500fe37, 0x07620a6dfb0b6cec3016adf3d3533c24024b95347856b79719bc0ba743a62c2c, 0x1574c7ef0c43545f36a8ca08bdbdd8b075d2959e2f322b731675de3e1982b4d0, 0x269e4b5b7a2eb21afd567970a717ceec5bd4184571c254fdc06e03a7ff8378f0] 21 | def x5_254_2_MDS_matrix : Matrix (Fin 2) (Fin 2) (ZMod bn254_prime) := ![![0x066f6f85d6f68a85ec10345351a23a3aaf07f38af8c952a7bceca70bd2af7ad5, 0x2b9d4b4110c9ae997782e1509b1d0fdb20a7c02bbd8bea7305462b9f8125b1e8],![0x0cc57cdbb08507d62bf67a4493cc262fb6c09d557013fff1f573f431221f8ff9, 0x1274e649a32ed355a31a6ed69724e1adade857e86eb5c3a121bcd147943203c8]] 22 | 23 | def x5_254_3_constants : List (ZMod bn254_prime) := [0x0ee9a592ba9a9518d05986d656f40c2114c4993c11bb29938d21d47304cd8e6e, 0x00f1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864, 0x08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5, 0x2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d0, 0x2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf2, 0x0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa, 0x28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d, 0x2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78, 0x234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc632, 0x15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428, 0x0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6, 0x1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c, 0x10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559, 0x1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6, 0x1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c8705, 0x04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d, 0x0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828, 0x099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b9, 0x052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6, 0x0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc, 0x119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd1, 0x03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09, 0x2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565, 0x005032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f9, 0x233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5, 0x05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280, 0x0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b, 0x2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0, 0x1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460, 0x12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc0, 0x0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e, 0x037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448, 0x05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f, 0x29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e, 0x20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f, 0x2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c887, 0x143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8, 0x0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1, 0x028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da53, 0x2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c, 0x0081c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e, 0x2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb38, 0x30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206, 0x1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad, 0x10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c, 0x2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef, 0x1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91, 0x07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a0, 0x21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750, 0x2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e, 0x2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e, 0x162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab, 0x2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311, 0x2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a, 0x1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9, 0x204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529, 0x0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c502, 0x174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54, 0x1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef, 0x066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a, 0x2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804, 0x13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649, 0x1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a, 0x00ef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1, 0x0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3, 0x29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba89, 0x2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be, 0x1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1, 0x151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c5, 0x04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100, 0x13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967, 0x01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e4, 0x2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02, 0x1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646, 0x041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d, 0x154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6, 0x0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4, 0x0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e, 0x06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626, 0x0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb, 0x04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e13, 0x2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758, 0x123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef, 0x2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e9, 0x0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d, 0x12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2, 0x21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a90035, 0x16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147, 0x1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2, 0x07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a, 0x05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc, 0x20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f, 0x04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db69, 0x27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a, 0x2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1, 0x1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b8, 0x15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a, 0x1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785, 0x25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c77, 0x15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67, 0x2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727, 0x002e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b, 0x2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2, 0x00b9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe, 0x0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c3512, 0x00248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d, 0x171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9, 0x170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a808, 0x29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1, 0x1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973, 0x1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f09, 0x22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38, 0x0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd, 0x11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e8284, 0x1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af, 0x2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466, 0x3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad, 0x2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086, 0x119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3, 0x1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd800, 0x28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6, 0x083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7, 0x0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b, 0x0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b, 0x2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591, 0x0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f178, 0x0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40, 0x1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4, 0x0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e504233, 0x0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873, 0x1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d, 0x2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc0, 0x1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb, 0x01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875, 0x1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e, 0x2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019, 0x23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b, 0x2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d59, 0x0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f, 0x2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8, 0x15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f88948, 0x193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f, 0x2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f, 0x1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d142, 0x04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b, 0x0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23, 0x058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c0, 0x1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a, 0x03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5, 0x23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a58, 0x0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2, 0x06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b, 0x118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d01, 0x13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1, 0x169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b, 0x04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d, 0x256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec, 0x30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2, 0x10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc792, 0x193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860, 0x18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d, 0x29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea6111, 0x10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711, 0x0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb, 0x16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa336, 0x0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a, 0x1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860, 0x0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d6, 0x161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b, 0x0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b, 0x1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f451, 0x2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556, 0x1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70, 0x2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf77, 0x23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea, 0x09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d, 0x188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc630, 0x3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f, 0x15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78, 0x1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc, 0x2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb, 0x202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60, 0x096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f, 0x054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4, 0x1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1, 0x21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc, 0x1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08, 0x0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100, 0x1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c2320, 0x0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870, 0x193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba, 0x102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f8, 0x0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1, 0x216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22, 0x1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e4228325161] 24 | def x5_254_3_MDS_matrix : Matrix (Fin 3) (Fin 3) (ZMod bn254_prime) := ![![0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b, 0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0, 0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d], ![0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771, 0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23, 0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa], ![0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7, 0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911, 0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0]] 25 | 26 | def x5_254_3 : Constants := { 27 | prime := bn254_prime, 28 | t := 3, 29 | t_ne_zero := by decide, 30 | R_F := 8, 31 | R_P := 57, 32 | round_constants := x5_254_3_constants, 33 | MDS_matrix := x5_254_3_MDS_matrix 34 | } 35 | 36 | def x5_254_2 : Constants := { 37 | prime := bn254_prime 38 | t := 2, 39 | t_ne_zero := by decide, 40 | R_F := 8, 41 | R_P := 56, 42 | round_constants := x5_254_2_constants, 43 | MDS_matrix := x5_254_2_MDS_matrix 44 | } 45 | 46 | end Constants -------------------------------------------------------------------------------- /lean-circuit/LeanCircuit/Poseidon/Correctness.lean: -------------------------------------------------------------------------------- 1 | import LeanCircuit 2 | import LeanCircuit.Poseidon.Constants 3 | import LeanCircuit.Poseidon.Spec 4 | import Mathlib 5 | import ProvenZk 6 | 7 | open Matrix 8 | open Semaphore (F Order) 9 | 10 | variable [Fact (Nat.Prime Order)] 11 | 12 | private lemma iff_to_eq {α} {a b: α} {k : α -> Prop }: a = b -> (k a ↔ k b) := by intro eq; rw [eq] 13 | 14 | def mds_matmul (cfg : Constants) (S : Vector cfg.F cfg.t) : Vector cfg.F cfg.t := (cfg.MDS_matrix ⬝ S.to_column).to_vector 15 | 16 | def full_round (cfg : Constants) (S C: Vector cfg.F cfg.t) : Vector cfg.F cfg.t := 17 | mds_matmul cfg (S.mapIdx fun i s => (s + C.get i) ^ 5) 18 | 19 | def partial_round (cfg : Constants) (S C: Vector cfg.F cfg.t) : Vector cfg.F cfg.t := 20 | let with_const := S.mapIdx fun i s => s + C.get i 21 | mds_matmul cfg (with_const.set 0 (with_const.get 0 ^ 5)) 22 | 23 | def full_rounds (cfg : Constants) (state_words : Vector cfg.F cfg.t) (round_constants_counter rounds : ℕ) : Vector cfg.F cfg.t := Id.run do 24 | let mut round_constants_counter := round_constants_counter 25 | let mut state_words := state_words 26 | 27 | for _ in [0:rounds] do 28 | let consts := Vector.ofFn (fun i => cfg.round_constants[round_constants_counter + i]!) 29 | state_words := full_round cfg state_words consts 30 | round_constants_counter := round_constants_counter + cfg.t 31 | state_words 32 | 33 | def partial_rounds (cfg : Constants) (state_words : Vector cfg.F cfg.t) (round_constants_counter rounds : ℕ) : Vector cfg.F cfg.t := Id.run do 34 | let mut round_constants_counter := round_constants_counter 35 | let mut state_words := state_words 36 | 37 | for _ in [0:rounds] do 38 | let consts := Vector.ofFn (fun i => cfg.round_constants[round_constants_counter + i]!) 39 | state_words := partial_round cfg state_words consts 40 | round_constants_counter := round_constants_counter + cfg.t 41 | state_words 42 | 43 | def full_rounds_cps 44 | (cfg : Constants) 45 | (full_round : Vector cfg.F cfg.t -> Vector cfg.F cfg.t -> (Vector cfg.F cfg.t -> Prop) -> Prop) 46 | (state: Vector cfg.F cfg.t) 47 | (init_const: Nat) 48 | (round_count: Nat) 49 | (k : Vector cfg.F cfg.t -> Prop): Prop := match round_count with 50 | | Nat.zero => k state 51 | | Nat.succ round_count => 52 | full_round state (Vector.ofFn fun i => cfg.round_constants[init_const + i]!) fun state' => 53 | full_rounds_cps cfg full_round state' (init_const + cfg.t) round_count k 54 | 55 | def half_rounds_cps 56 | (cfg : Constants) 57 | (half_round : Vector cfg.F cfg.t -> Vector cfg.F cfg.t -> (Vector cfg.F cfg.t -> Prop) -> Prop) 58 | (state: Vector cfg.F cfg.t) 59 | (init_const: Nat) 60 | (round_count: Nat) 61 | (k : Vector cfg.F cfg.t -> Prop): Prop := match round_count with 62 | | Nat.zero => k state 63 | | Nat.succ round_count => 64 | half_round state (Vector.ofFn fun i => cfg.round_constants[init_const + i]!) fun state' => 65 | half_rounds_cps cfg half_round state' (init_const + cfg.t) round_count k 66 | 67 | lemma sbox_uncps (A : F) (k : F -> Prop): Semaphore.sbox A k = k (A ^ 5) := by 68 | unfold Semaphore.sbox 69 | simp [Gates.mul] 70 | apply iff_to_eq 71 | repeat (rw [pow_succ]) 72 | rw [pow_zero, mul_one, mul_assoc] 73 | 74 | lemma mds_3_uncps (S : Vector F 3) (k : Vector F 3 -> Prop): 75 | Semaphore.mds_3 S k = k (mds_matmul Constants.x5_254_3 S) := by 76 | simp [Semaphore.mds_3, Gates.add, Gates.mul] 77 | apply iff_to_eq 78 | simp [mds_matmul, Constants.x5_254_3, Constants.x5_254_3_MDS_matrix] 79 | simp [Vector.to_column, Matrix.to_vector, Vector.ofFn] 80 | repeat ( 81 | apply congrArg₂ 82 | { 83 | simp [getElem, Matrix.of, Matrix.mul, Matrix.dotProduct] 84 | simp [Finset.sum, Finset.univ, Fintype.elems] 85 | rw [←add_assoc] 86 | conv => lhs; simp [mul_comm] 87 | } 88 | ) 89 | rfl 90 | 91 | lemma mds_2_uncps (S : Vector F 2) (k : Vector F 2 -> Prop): 92 | Semaphore.mds_2 S k = k (mds_matmul Constants.x5_254_2 S) := by 93 | simp [Semaphore.mds_2, Gates.add, Gates.mul] 94 | apply iff_to_eq 95 | simp [mds_matmul, Constants.x5_254_2, Constants.x5_254_2_MDS_matrix] 96 | simp [Vector.to_column, Matrix.to_vector, Vector.ofFn] 97 | repeat ( 98 | apply congrArg₂ 99 | { 100 | simp [getElem, Matrix.of, Matrix.mul, Matrix.dotProduct] 101 | simp [Finset.sum, Finset.univ, Fintype.elems] 102 | conv => lhs; simp [mul_comm] 103 | } 104 | ) 105 | rfl 106 | 107 | lemma full_round_3_uncps (S C: Vector F 3) (k : Vector F 3 -> Prop): 108 | Semaphore.fullRound_3_3 S C k = k (full_round Constants.x5_254_3 S C) := by 109 | unfold Semaphore.fullRound_3_3 110 | unfold Gates.add 111 | simp [Gates.add, sbox_uncps, mds_3_uncps, full_round] 112 | apply iff_to_eq 113 | have : ∀ {α} {v : Vector α 3}, vec![v[0], v[1], v[2]] = v := by 114 | intro α v 115 | conv => rhs; rw [←Vector.ofFn_get v] 116 | rw [this] 117 | congr 118 | conv => rhs ; rw [←Vector.ofFn_get S] 119 | 120 | lemma full_round_2_uncps (S C: Vector F 2) (k : Vector F 2 -> Prop): 121 | Semaphore.fullRound_2_2 S C k = k (full_round Constants.x5_254_2 S C) := by 122 | unfold Semaphore.fullRound_2_2 123 | unfold Gates.add 124 | simp [Gates.add, sbox_uncps, mds_2_uncps, full_round] 125 | apply iff_to_eq 126 | have : ∀ {α} {v : Vector α 2}, vec![v[0], v[1]] = v := by 127 | intro α v 128 | conv => rhs; rw [←Vector.ofFn_get v] 129 | rw [this] 130 | congr 131 | conv => rhs ; rw [←Vector.ofFn_get S] 132 | 133 | lemma half_round_3_uncps (S C: Vector F 3) (k : Vector F 3 -> Prop): 134 | Semaphore.halfRound_3_3 S C k = k (partial_round Constants.x5_254_3 S C) := by 135 | unfold Semaphore.halfRound_3_3 136 | unfold Gates.add 137 | simp [Gates.add, sbox_uncps, mds_3_uncps, partial_round] 138 | apply iff_to_eq 139 | have : ∀ {α} {v : Vector α 3}, vec![v[0], v[1], v[2]] = v := by 140 | intro α v 141 | conv => rhs; rw [←Vector.ofFn_get v] 142 | rw [this] 143 | congr 144 | conv => rhs ; rw [←Vector.ofFn_get S] 145 | 146 | lemma half_round_2_uncps (S C: Vector F 2) (k : Vector F 2 -> Prop): 147 | Semaphore.halfRound_2_2 S C k = k (partial_round Constants.x5_254_2 S C) := by 148 | unfold Semaphore.halfRound_2_2 149 | unfold Gates.add 150 | simp [Gates.add, sbox_uncps, mds_2_uncps, partial_round] 151 | apply iff_to_eq 152 | have : ∀ {α} {v : Vector α 2}, vec![v[0], v[1]] = v := by 153 | intro α v 154 | conv => rhs; rw [←Vector.ofFn_get v] 155 | rw [this] 156 | congr 157 | conv => rhs ; rw [←Vector.ofFn_get S] 158 | 159 | lemma partial_rounds_uncps 160 | {cfg : Constants} 161 | {S : Vector cfg.F cfg.t} 162 | {start count : Nat} 163 | {k : Vector cfg.F cfg.t -> Prop} 164 | {half_round_cps : Vector cfg.F cfg.t -> Vector cfg.F cfg.t -> (Vector cfg.F cfg.t -> Prop) -> Prop} 165 | {half_round_uncps : ∀ S C k, half_round_cps S C k = k (partial_round cfg S C)} 166 | : 167 | half_rounds_cps cfg half_round_cps S start count k = k (partial_rounds cfg S start count) := by 168 | induction count generalizing start S with 169 | | zero => 170 | simp [half_rounds_cps, partial_rounds, forIn, Std.Range.forIn, Std.Range.forIn.loop, Id.run] 171 | | succ count ih => 172 | unfold half_rounds_cps 173 | rw [half_round_uncps, ih] 174 | unfold partial_rounds 175 | simp [Id.run, forIn] 176 | apply iff_to_eq 177 | simp [Std.Range.counter_elide_fst] 178 | rw [←zero_add (Nat.succ count), Std.Range.forIn_startSucc] 179 | have : Nat.succ 0 = 0 + 1 := by rfl 180 | rw [this] 181 | have : 0 + Nat.succ count = count + 1 := by simp_arith 182 | rw [this] 183 | rw [←Std.Range.forIn_ixShift] 184 | apply congrArg₂ 185 | { simp } 186 | funext i r 187 | congr 188 | funext i' 189 | have : start + cfg.t + i * cfg.t + ↑i' = start + (i + 1) * cfg.t + ↑i' := by linarith 190 | rw [this] 191 | 192 | lemma partial_rounds_2_uncps 193 | {S : Vector F 2} 194 | {start count : Nat} 195 | {k : Vector F 2 -> Prop}: 196 | half_rounds_cps Constants.x5_254_2 Semaphore.halfRound_2_2 S start count k = k (partial_rounds Constants.x5_254_2 S start count) := by 197 | apply partial_rounds_uncps 198 | apply half_round_2_uncps 199 | 200 | lemma partial_rounds_3_uncps 201 | {S : Vector F 3} 202 | {start count : Nat} 203 | {k : Vector F 3 -> Prop}: 204 | half_rounds_cps Constants.x5_254_3 Semaphore.halfRound_3_3 S start count k = k (partial_rounds Constants.x5_254_3 S start count) := by 205 | apply partial_rounds_uncps 206 | apply half_round_3_uncps 207 | 208 | lemma full_rounds_uncps 209 | {cfg : Constants} 210 | {S : Vector cfg.F cfg.t} 211 | {start count : Nat} 212 | {k : Vector cfg.F cfg.t -> Prop} 213 | {full_round_cps : Vector cfg.F cfg.t -> Vector cfg.F cfg.t -> (Vector cfg.F cfg.t -> Prop) -> Prop} 214 | {full_round_uncps : ∀ S C k, full_round_cps S C k = k (full_round cfg S C)} 215 | : 216 | full_rounds_cps cfg full_round_cps S start count k = k (full_rounds cfg S start count) := by 217 | induction count generalizing start S with 218 | | zero => 219 | simp [full_rounds_cps, full_rounds, forIn, Std.Range.forIn, Std.Range.forIn.loop, Id.run] 220 | | succ count ih => 221 | unfold full_rounds_cps 222 | rw [full_round_uncps, ih] 223 | unfold full_rounds 224 | simp [Id.run, forIn] 225 | apply iff_to_eq 226 | simp [Std.Range.counter_elide_fst] 227 | rw [←zero_add (Nat.succ count), Std.Range.forIn_startSucc] 228 | have : Nat.succ 0 = 0 + 1 := by rfl 229 | rw [this] 230 | have : 0 + Nat.succ count = count + 1 := by simp_arith 231 | rw [this] 232 | rw [←Std.Range.forIn_ixShift] 233 | apply congrArg₂ 234 | { simp } 235 | funext i r 236 | congr 237 | funext i' 238 | have : start + cfg.t + i * cfg.t + ↑i' = start + (i + 1) * cfg.t + ↑i' := by linarith 239 | rw [this] 240 | 241 | lemma full_rounds_2_uncps 242 | {S : Vector F 2} 243 | {start count : Nat} 244 | {k : Vector F 2 -> Prop}: 245 | full_rounds_cps Constants.x5_254_2 Semaphore.fullRound_2_2 S start count k = k (full_rounds Constants.x5_254_2 S start count) := by 246 | apply full_rounds_uncps 247 | apply full_round_2_uncps 248 | 249 | lemma full_rounds_3_uncps 250 | {S : Vector F 3} 251 | {start count : Nat} 252 | {k : Vector F 3 -> Prop}: 253 | full_rounds_cps Constants.x5_254_3 Semaphore.fullRound_3_3 S start count k = k (full_rounds Constants.x5_254_3 S start count) := by 254 | apply full_rounds_uncps 255 | apply full_round_3_uncps 256 | 257 | def looped_poseidon_2 (inp : Vector F 2) (k: Vector F 2 -> Prop): Prop := 258 | full_rounds_cps Constants.x5_254_2 Semaphore.fullRound_2_2 inp 0 4 fun state => 259 | half_rounds_cps Constants.x5_254_2 Semaphore.halfRound_2_2 state 8 56 fun state' => 260 | full_rounds_cps Constants.x5_254_2 Semaphore.fullRound_2_2 state' 120 4 k 261 | 262 | lemma fold_vec_2 {v : Vector F 2}: vec![v[0], v[1]] = v := by 263 | conv => rhs; rw [←Vector.ofFn_get v] 264 | 265 | def looped_poseidon_3 (inp : Vector F 3) (k: Vector F 3 -> Prop): Prop := 266 | full_rounds_cps Constants.x5_254_3 Semaphore.fullRound_3_3 inp 0 4 fun state => 267 | half_rounds_cps Constants.x5_254_3 Semaphore.halfRound_3_3 state 12 57 fun state' => 268 | full_rounds_cps Constants.x5_254_3 Semaphore.fullRound_3_3 state' 183 4 k 269 | 270 | lemma fold_vec_3 {v : Vector F 3}: vec![v[0], v[1], v[2]] = v := by 271 | conv => rhs; rw [←Vector.ofFn_get v] 272 | 273 | set_option maxRecDepth 2048 274 | 275 | theorem looped_poseidon_2_go (inp : Vector F 2) (k : Vector F 2 -> Prop): 276 | Semaphore.poseidon_2 inp k = looped_poseidon_2 inp k := by 277 | unfold looped_poseidon_2 278 | unfold Semaphore.poseidon_2 279 | simp [full_rounds_cps, half_rounds_cps, getElem!, fold_vec_2, Vector.ofFn] 280 | rfl 281 | 282 | theorem looped_poseidon_3_go (inp : Vector F 3) (k : Vector F 3 -> Prop): 283 | Semaphore.poseidon_3 inp k = looped_poseidon_3 inp k := by 284 | unfold looped_poseidon_3 285 | unfold Semaphore.poseidon_3 286 | simp [full_rounds_cps, half_rounds_cps, getElem!, fold_vec_3, Vector.ofFn] 287 | rfl 288 | 289 | set_option maxRecDepth 512 290 | 291 | def perm_folded (cfg : Constants) (input_words : Vector cfg.F cfg.t): Vector cfg.F cfg.t := Id.run do 292 | let R_f := cfg.R_F / 2 293 | let mut round_constants_counter := 0 294 | let mut state_words := input_words 295 | 296 | state_words := full_rounds cfg state_words round_constants_counter R_f 297 | round_constants_counter := R_f * cfg.t 298 | 299 | state_words := partial_rounds cfg state_words round_constants_counter cfg.R_P 300 | round_constants_counter := R_f * cfg.t + cfg.R_P * cfg.t 301 | 302 | state_words := full_rounds cfg state_words round_constants_counter R_f 303 | 304 | state_words 305 | 306 | theorem perm_folded_go (cfg : Constants) (input_words : Vector cfg.F cfg.t): 307 | Poseidon.perm cfg input_words = perm_folded cfg input_words := by 308 | unfold Poseidon.perm 309 | unfold perm_folded 310 | unfold full_rounds 311 | unfold partial_rounds 312 | simp [Id.run, forIn] 313 | simp [Std.Range.counter_elide_fst] 314 | cases cfg; rename_i prime t t_ne_zero R_F R_P round_constants MDS_matrix 315 | cases t 316 | { contradiction } 317 | rename_i t' 318 | simp at * 319 | apply congrArg₂ 320 | { 321 | apply congrArg₂ 322 | { 323 | apply congrArg 324 | funext i r 325 | unfold full_round 326 | unfold mds_matmul 327 | simp 328 | apply congrArg 329 | apply congrArg 330 | apply congrArg 331 | apply congrArg 332 | rw [Vector.setLoop_def (f := fun _ r => r ^ 5)] 333 | rw [Vector.setLoop_def (f := fun i' r => r + round_constants[i * Nat.succ t' + i']!)] 334 | simp [Vector.setLoop_mapIdx, Vector.mapIdx_compose] 335 | rw [Vector.mapIdx_mod] 336 | } 337 | { 338 | funext i r 339 | rw [Vector.setLoop_def (f := fun i' r => r + round_constants[R_F / 2 * Nat.succ t' + i * Nat.succ t' + i']!)] 340 | rw [Vector.setLoop_mapIdx] 341 | apply congrArg 342 | unfold partial_round 343 | simp 344 | unfold mds_matmul 345 | simp 346 | apply congrArg 347 | apply congrArg 348 | apply congrArg 349 | rw [Vector.mapIdx_mod] 350 | } 351 | } 352 | { 353 | funext i r 354 | apply congrArg 355 | unfold full_round 356 | unfold mds_matmul 357 | simp 358 | apply congrArg 359 | apply congrArg 360 | apply congrArg 361 | rw [Vector.setLoop_def (f := fun _ r => r ^ 5)] 362 | rw [Vector.setLoop_def (f := fun i' r => r + round_constants[R_F / 2 * Nat.succ t' + R_P * Nat.succ t' + i * Nat.succ t' + i']!)] 363 | simp [Vector.setLoop_mapIdx, Vector.mapIdx_compose] 364 | rw [Vector.mapIdx_mod] 365 | } 366 | 367 | theorem poseidon_3_correct (inp : Vector F 3) (k : Vector F 3 -> Prop): 368 | Semaphore.poseidon_3 inp k = k (Poseidon.perm Constants.x5_254_3 inp) := by 369 | simp [ 370 | looped_poseidon_3_go, 371 | looped_poseidon_3, 372 | full_rounds_uncps, 373 | partial_rounds_3_uncps, 374 | full_rounds_3_uncps, 375 | perm_folded_go, 376 | perm_folded 377 | ] 378 | rfl 379 | 380 | theorem poseidon_2_correct (inp : Vector F 2) (k : Vector F 2 -> Prop): 381 | Semaphore.poseidon_2 inp k = k (Poseidon.perm Constants.x5_254_2 inp) := by 382 | simp [ 383 | looped_poseidon_2_go, 384 | looped_poseidon_2, 385 | full_rounds_uncps, 386 | partial_rounds_2_uncps, 387 | full_rounds_2_uncps, 388 | perm_folded_go, 389 | perm_folded 390 | ] 391 | rfl -------------------------------------------------------------------------------- /lean-circuit/LeanCircuit/Poseidon/Spec.lean: -------------------------------------------------------------------------------- 1 | import Mathlib 2 | import ProvenZk 3 | import LeanCircuit.Poseidon.Constants 4 | 5 | open Matrix 6 | 7 | namespace Poseidon 8 | 9 | def perm (cfg : Constants) (input_words : Vector cfg.F cfg.t): Vector cfg.F cfg.t := Id.run do 10 | let R_f := cfg.R_F / 2 11 | let mut round_constants_counter := 0 12 | let mut state_words := input_words 13 | for _ in [0:R_f] do 14 | for i in [0:cfg.t] do 15 | state_words := state_words.set i (state_words.get i + cfg.round_constants[round_constants_counter]!) 16 | round_constants_counter := round_constants_counter + 1 17 | for i in [0:cfg.t] do 18 | state_words := state_words.set i (state_words.get i ^ 5) 19 | state_words := (cfg.MDS_matrix ⬝ state_words.to_column).to_vector 20 | 21 | for _ in [0:cfg.R_P] do 22 | for i in [0:cfg.t] do 23 | state_words := state_words.set i (state_words.get i + cfg.round_constants[round_constants_counter]!) 24 | round_constants_counter := round_constants_counter + 1 25 | state_words := state_words.set 0 (state_words.get 0 ^ 5) 26 | state_words := (cfg.MDS_matrix ⬝ state_words.to_column).to_vector 27 | 28 | for _ in [0:R_f] do 29 | for i in [0:cfg.t] do 30 | state_words := state_words.set i (state_words.get i + cfg.round_constants[round_constants_counter]!) 31 | round_constants_counter := round_constants_counter + 1 32 | for i in [0:cfg.t] do 33 | state_words := state_words.set i (state_words.get i ^ 5) 34 | state_words := (cfg.MDS_matrix ⬝ state_words.to_column).to_vector 35 | 36 | state_words 37 | 38 | theorem test_vector_correct_x5_254_3: 39 | perm Constants.x5_254_3 vec![0,1,2] = vec![0x115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a, 0x0fca49b798923ab0239de1c9e7a4a9a2210312b6a2f616d18b5a87f9b628ae29, 0x0e7ae82e40091e63cbd4f16a6d16310b3729d4b6e138fcf54110e2867045a30c] := 40 | by eq_refl 41 | 42 | end Poseidon -------------------------------------------------------------------------------- /lean-circuit/LeanCircuit/SemanticEquivalence.lean: -------------------------------------------------------------------------------- 1 | import ProvenZk.Binary 2 | import ProvenZk.Hash 3 | import ProvenZk.Merkle 4 | 5 | import LeanCircuit 6 | import LeanCircuit.Poseidon.Spec 7 | import LeanCircuit.Poseidon.Correctness 8 | 9 | open Semaphore (F Order) 10 | 11 | variable [Fact (Nat.Prime Order)] 12 | 13 | abbrev D := 20 14 | 15 | def embed_dir : Dir -> F 16 | | x => Dir.toZMod x 17 | 18 | def embed_dir_vector {depth} (ix: Vector Dir depth) : Vector F depth := 19 | Vector.map embed_dir ix 20 | 21 | lemma dir_embed_recover {d : Dir} : Dir.nat_to_dir (embed_dir d).val = d := by 22 | cases d <;> rfl 23 | 24 | @[simp] 25 | lemma dir_embed_recover_vector {depth} (ix: Vector Dir depth) : 26 | Dir.create_dir_vec (embed_dir_vector ix) = ix := by 27 | simp [Dir.create_dir_vec, embed_dir_vector, dir_embed_recover] 28 | apply Vector.eq 29 | simp 30 | 31 | @[simp] 32 | lemma embed_dir_vector_reverse {depth} (ix : Vector Dir depth) : 33 | embed_dir_vector ix.reverse = (embed_dir_vector ix).reverse := by 34 | simp [embed_dir_vector] 35 | apply Vector.eq 36 | simp [Vector.toList_reverse, List.map_reverse] 37 | 38 | lemma embed_dir_vector_is_binary {depth} (ix : Vector Dir depth) : 39 | is_vector_binary (embed_dir_vector ix) := by 40 | simp [is_vector_binary, embed_dir_vector] 41 | induction ix using Vector.inductionOn with 42 | | h_nil => simp [is_vector_binary] 43 | | @h_cons n d ds ih => 44 | simp [is_vector_binary_cons] 45 | apply And.intro 46 | { simp [embed_dir, is_bit]; cases d <;> simp } 47 | { assumption } 48 | 49 | def poseidon₁ : Hash F 1 := fun a => (Poseidon.perm Constants.x5_254_2 vec![0, a.get 0]).get 0 50 | 51 | lemma Poseidon1_uncps (a : F) (k : F -> Prop) : Semaphore.Poseidon1 a k ↔ k (poseidon₁ vec![a]) := by 52 | simp [Semaphore.Poseidon1, poseidon₁, poseidon_2_correct, getElem] 53 | 54 | def poseidon₂ : Hash F 2 := fun a => (Poseidon.perm Constants.x5_254_3 vec![0, a.get 0, a.get 1]).get 0 55 | 56 | lemma Poseidon2_uncps (a b : F) (k : F -> Prop) : Semaphore.Poseidon2 a b k ↔ k (poseidon₂ vec![a, b]) := by 57 | simp [Semaphore.Poseidon2, poseidon₂, poseidon_3_correct, getElem] 58 | rfl 59 | 60 | lemma MerkleTreeRecoverRound_uncps {dir hash sibling : F} {k : F -> Prop}: 61 | Semaphore.MerkleTreeRecoverRound dir hash sibling k ↔ 62 | is_bit dir ∧ k (match Dir.nat_to_dir dir.val with 63 | | Dir.left => poseidon₂ vec![hash, sibling] 64 | | Dir.right => poseidon₂ vec![sibling, hash]) := by 65 | simp [Semaphore.MerkleTreeRecoverRound, Gates.is_bool] 66 | intro hb 67 | rw [Poseidon2_uncps, Poseidon2_uncps] 68 | cases hb <;> { 69 | simp [*, Gates.select, Gates.is_bool, Dir.nat_to_dir] 70 | try rfl 71 | } 72 | 73 | def merkle_tree_recover_rounds (Leaf : F) (PathIndices Siblings : Vector F n) (k : F -> Prop) : Prop := 74 | match n with 75 | | Nat.zero => k Leaf 76 | | Nat.succ _ => Semaphore.MerkleTreeRecoverRound PathIndices.head Leaf Siblings.head fun next => 77 | merkle_tree_recover_rounds next PathIndices.tail Siblings.tail k 78 | 79 | lemma merkle_tree_recover_rounds_uncps 80 | {Leaf : F} 81 | {PathIndices Siblings : Vector F n} 82 | {k : F -> Prop}: 83 | merkle_tree_recover_rounds Leaf PathIndices Siblings k ↔ 84 | is_vector_binary PathIndices ∧ k (MerkleTree.recover_tail poseidon₂ (Dir.create_dir_vec PathIndices) Siblings Leaf) := by 85 | induction PathIndices, Siblings using Vector.inductionOn₂ generalizing Leaf with 86 | | nil => 87 | simp [is_vector_binary] 88 | rfl 89 | | @cons n ix sib ixes sibs ih => 90 | simp [MerkleTree.recover_tail_reverse_equals_recover, MerkleTree.recover_tail, merkle_tree_recover_rounds] 91 | simp [MerkleTreeRecoverRound_uncps, is_vector_binary_cons, and_assoc, ih] 92 | intros 93 | rfl 94 | 95 | lemma MerkleTreeInclusionProof_looped (Leaf: F) (PathIndices: Vector F D) (Siblings: Vector F D) (k: F -> Prop): 96 | Semaphore.MerkleTreeInclusionProof_20_20 Leaf PathIndices Siblings k = 97 | merkle_tree_recover_rounds Leaf PathIndices Siblings k := by 98 | unfold Semaphore.MerkleTreeInclusionProof_20_20 99 | simp [merkle_tree_recover_rounds] 100 | rw [←Vector.ofFn_get (v := PathIndices)] 101 | rw [←Vector.ofFn_get (v := Siblings)] 102 | rfl 103 | 104 | lemma MerkleTreeInclusionProof_20_20_uncps {Leaf : F} {PathIndices Siblings : Vector F D} {k : F -> Prop}: 105 | Semaphore.MerkleTreeInclusionProof_20_20 Leaf PathIndices Siblings k ↔ 106 | is_vector_binary PathIndices ∧ k (MerkleTree.recover_tail poseidon₂ (Dir.create_dir_vec PathIndices) Siblings Leaf) := by 107 | simp [MerkleTreeInclusionProof_looped, merkle_tree_recover_rounds_uncps] 108 | 109 | abbrev secret (IdentityNullifier: F) (IdentityTrapdoor: F) : F := 110 | poseidon₂ vec![IdentityNullifier, IdentityTrapdoor] 111 | 112 | abbrev identity_commitment (IdentityNullifier: F) (IdentityTrapdoor: F) : F := 113 | poseidon₁ vec![(secret IdentityNullifier IdentityTrapdoor)] 114 | 115 | abbrev nullifier_hash (ExternalNullifier: F) (IdentityNullifier: F) : F := 116 | poseidon₂ vec![ExternalNullifier, IdentityNullifier] 117 | 118 | def circuit_sem (IdentityNullifier IdentityTrapdoor ExternalNullifier NullifierHash Root: F) (Path Proof: Vector F D): Prop := 119 | NullifierHash = nullifier_hash ExternalNullifier IdentityNullifier ∧ 120 | is_vector_binary Path ∧ 121 | MerkleTree.recover poseidon₂ (Dir.create_dir_vec Path).reverse Proof.reverse (identity_commitment IdentityNullifier IdentityTrapdoor) = Root 122 | 123 | theorem circuit_semantics {IdentityNullifier IdentityTrapdoor SignalHash ExternalNullifier NullifierHash Root: F} {Path Proof: Vector F D}: 124 | Semaphore.circuit IdentityNullifier IdentityTrapdoor Path Proof SignalHash ExternalNullifier NullifierHash Root ↔ 125 | circuit_sem IdentityNullifier IdentityTrapdoor ExternalNullifier NullifierHash Root Path Proof := by 126 | simp [ 127 | circuit_sem, 128 | Semaphore.circuit, 129 | Poseidon2_uncps, 130 | Poseidon1_uncps, 131 | MerkleTreeInclusionProof_20_20_uncps, 132 | Gates.eq, 133 | nullifier_hash, 134 | Dir.create_dir_vec, 135 | ←MerkleTree.recover_tail_reverse_equals_recover 136 | ] 137 | apply Iff.intro 138 | case mp => 139 | intros 140 | casesm* (_ ∧ _) 141 | rw [←Vector.ofFn_get (v := Path)] 142 | rw [←Vector.ofFn_get (v := Proof)] 143 | subst_vars 144 | apply And.intro 145 | {rfl} 146 | apply And.intro 147 | {assumption} 148 | {rfl} 149 | case mpr => 150 | intro h 151 | cases h; rename_i h₁ h₂ 152 | cases h₂; rename_i h₂ h₃ 153 | rw [←Vector.ofFn_get (v := Path)] at h₂ 154 | rw [←Vector.ofFn_get (v := Path)] at h₃ 155 | rw [←Vector.ofFn_get (v := Proof)] at h₃ 156 | subst_vars 157 | apply And.intro 158 | {rfl} 159 | apply And.intro 160 | assumption 161 | {rfl} -------------------------------------------------------------------------------- /lean-circuit/Main.lean: -------------------------------------------------------------------------------- 1 | import ProvenZk.Binary 2 | import ProvenZk.Hash 3 | import ProvenZk.Merkle 4 | 5 | import LeanCircuit 6 | import LeanCircuit.SemanticEquivalence 7 | 8 | open Semaphore (F Order) 9 | 10 | variable [Fact (Nat.Prime Order)] 11 | 12 | theorem always_possible_to_signal 13 | (IdentityNullifier IdentityTrapdoor SignalHash ExtNullifier : F) 14 | (Tree : MerkleTree F poseidon₂ 20) 15 | (Path : Vector Dir 20) 16 | (commitment_in_tree : Tree.item_at Path = identity_commitment IdentityNullifier IdentityTrapdoor) 17 | : 18 | Semaphore.circuit 19 | IdentityNullifier 20 | IdentityTrapdoor 21 | (embed_dir_vector Path.reverse) 22 | (Tree.proof Path).reverse 23 | SignalHash 24 | ExtNullifier 25 | (nullifier_hash ExtNullifier IdentityNullifier) 26 | Tree.root 27 | := by 28 | rw [circuit_semantics, ←MerkleTree.recover_proof_is_root, commitment_in_tree] 29 | simp [circuit_sem] 30 | apply embed_dir_vector_is_binary 31 | 32 | theorem signaller_is_in_tree 33 | (IdentityNullifier IdentityTrapdoor SignalHash ExtNullifier NullifierHash : F) 34 | (Tree : MerkleTree F poseidon₂ 20) 35 | (Path Proof: Vector F 20) 36 | [Fact (perfect_hash poseidon₂)] 37 | : 38 | Semaphore.circuit IdentityNullifier IdentityTrapdoor Path Proof SignalHash ExtNullifier NullifierHash Tree.root → 39 | Tree.item_at (Dir.create_dir_vec Path.reverse) = identity_commitment IdentityNullifier IdentityTrapdoor := by 40 | simp [circuit_semantics, circuit_sem] 41 | intros 42 | apply MerkleTree.proof_ceritfies_item 43 | assumption 44 | 45 | theorem no_double_signal_with_same_commitment 46 | (IdentityNullifier₁ IdentityNullifier₂ IdentityTrapdoor₁ IdentityTrapdoor₂ SignalHash₁ SignalHash₂ ExtNullifier₁ ExtNullifier₂ NullifierHash₁ NullifierHash₂ Root₁ Root₂ : F) 47 | (Path₁ Proof₁ Path₂ Proof₂: Vector F 20) 48 | [Fact (perfect_hash poseidon₁)] 49 | [Fact (perfect_hash poseidon₂)] 50 | : 51 | Semaphore.circuit IdentityNullifier₁ IdentityTrapdoor₁ Path₁ Proof₁ SignalHash₁ ExtNullifier₁ NullifierHash₁ Root₁ → 52 | Semaphore.circuit IdentityNullifier₂ IdentityTrapdoor₂ Path₂ Proof₂ SignalHash₂ ExtNullifier₂ NullifierHash₂ Root₂ → 53 | ExtNullifier₁ = ExtNullifier₂ → 54 | identity_commitment IdentityNullifier₁ IdentityTrapdoor₁ = identity_commitment IdentityNullifier₂ IdentityTrapdoor₂ → 55 | NullifierHash₁ = NullifierHash₂ := by 56 | simp [circuit_semantics, circuit_sem, secret, Vector.eq_cons_iff] 57 | intros 58 | subst_vars 59 | rfl 60 | 61 | def main : IO Unit := pure () -------------------------------------------------------------------------------- /lean-circuit/lake-manifest.json: -------------------------------------------------------------------------------- 1 | {"version": 4, 2 | "packagesDir": "lake-packages", 3 | "packages": 4 | [{"git": 5 | {"url": "https://github.com/EdAyers/ProofWidgets4", 6 | "subDir?": null, 7 | "rev": "c43db94a8f495dad37829e9d7ad65483d68c86b8", 8 | "name": "proofwidgets", 9 | "inputRev?": "v0.0.11"}}, 10 | {"git": 11 | {"url": "https://github.com/mhuisi/lean4-cli.git", 12 | "subDir?": null, 13 | "rev": "5a858c32963b6b19be0d477a30a1f4b6c120be7e", 14 | "name": "Cli", 15 | "inputRev?": "nightly"}}, 16 | {"git": 17 | {"url": "https://github.com/reilabs/proven-zk.git", 18 | "subDir?": null, 19 | "rev": "08431b93eeef80f6acbf3d6a6401c02d849f6864", 20 | "name": "ProvenZK", 21 | "inputRev?": "v1.0.0"}}, 22 | {"git": 23 | {"url": "https://github.com/leanprover-community/mathlib4.git", 24 | "subDir?": null, 25 | "rev": "ea67efc21e4e1496f0a1d954cd0c0a952523133a", 26 | "name": "mathlib", 27 | "inputRev?": "ea67efc21e4e1496f0a1d954cd0c0a952523133a"}}, 28 | {"git": 29 | {"url": "https://github.com/gebner/quote4", 30 | "subDir?": null, 31 | "rev": "c0d9516f44d07feee01c1103c8f2f7c24a822b55", 32 | "name": "Qq", 33 | "inputRev?": "master"}}, 34 | {"git": 35 | {"url": "https://github.com/JLimperg/aesop", 36 | "subDir?": null, 37 | "rev": "f04538ab6ad07642368cf11d2702acc0a9b4bcee", 38 | "name": "aesop", 39 | "inputRev?": "master"}}, 40 | {"git": 41 | {"url": "https://github.com/leanprover/std4", 42 | "subDir?": null, 43 | "rev": "dff883c55395438ae2a5c65ad5ddba084b600feb", 44 | "name": "std", 45 | "inputRev?": "main"}}]} 46 | -------------------------------------------------------------------------------- /lean-circuit/lakefile.lean: -------------------------------------------------------------------------------- 1 | import Lake 2 | open Lake DSL 3 | 4 | package «lean-circuit» { 5 | -- add package configuration options here 6 | } 7 | 8 | require mathlib from git 9 | "https://github.com/leanprover-community/mathlib4.git"@"ea67efc21e4e1496f0a1d954cd0c0a952523133a" 10 | 11 | require ProvenZK from git 12 | "https://github.com/reilabs/proven-zk.git"@"v1.0.0" 13 | 14 | lean_lib LeanCircuit { 15 | -- add library configuration options here 16 | } 17 | 18 | @[default_target] 19 | lean_exe «lean-circuit» { 20 | moreLeanArgs := #["--tstack=1000000"] 21 | root := `Main 22 | } 23 | -------------------------------------------------------------------------------- /lean-circuit/lean-toolchain: -------------------------------------------------------------------------------- 1 | leanprover/lean4:nightly-2023-07-12 2 | -------------------------------------------------------------------------------- /run.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | 3 | go mod download 4 | go build -o gnark-lean-demo.exe -v ./... 5 | .\gnark-lean-demo.exe extract-circuit --out=lean-circuit/LeanCircuit.lean -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | go mod download 4 | go build -o gnark-lean-demo -v ./... 5 | ./gnark-lean-demo extract-circuit --out=lean-circuit/LeanCircuit.lean --------------------------------------------------------------------------------